mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-14 11:45:02 +01:00
queue worker task
This commit is contained in:
parent
f860714b2b
commit
800ccae604
8 changed files with 111 additions and 36 deletions
|
|
@ -14,14 +14,24 @@ use crate::{
|
||||||
};
|
};
|
||||||
use connection::{ChannelId, ConnectionId};
|
use connection::{ChannelId, ConnectionId};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::{Debug, Formatter},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GlobalData {
|
pub struct GlobalData {
|
||||||
inner: Arc<Mutex<GlobalDataInner>>,
|
inner: Arc<Mutex<GlobalDataInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for GlobalData {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("[global data]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for GlobalData {
|
impl Default for GlobalData {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ macro_rules! newtype_id {
|
||||||
|
|
||||||
impl ::std::fmt::Display for $name {
|
impl ::std::fmt::Display for $name {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||||
self.0.fmt(f)
|
::std::fmt::Display::fmt(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,18 @@ use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
fmt::{Debug, Display, Formatter},
|
||||||
sync::{atomic::AtomicUsize, Arc},
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
};
|
};
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
pub type Queue = Arc<RawQueue>;
|
pub type Queue = Arc<QueueInner>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum QueueEvent {}
|
||||||
|
|
||||||
|
pub type QueueEventSender = mpsc::Sender<QueueEvent>;
|
||||||
|
pub type QueueEventReceiver = mpsc::Receiver<QueueEvent>;
|
||||||
|
|
||||||
newtype_id!(pub QueueId);
|
newtype_id!(pub QueueId);
|
||||||
|
|
||||||
|
|
@ -26,8 +34,14 @@ impl Borrow<str> for QueueName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for QueueName {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RawQueue {
|
pub struct QueueInner {
|
||||||
pub id: QueueId,
|
pub id: QueueId,
|
||||||
pub name: QueueName,
|
pub name: QueueName,
|
||||||
pub messages: Mutex<Vec<Message>>, // use a concurrent linked list???
|
pub messages: Mutex<Vec<Message>>, // use a concurrent linked list???
|
||||||
|
|
@ -38,6 +52,7 @@ pub struct RawQueue {
|
||||||
/// If auto-delete is enabled, it keeps track of the consumer count.
|
/// If auto-delete is enabled, it keeps track of the consumer count.
|
||||||
pub deletion: QueueDeletion,
|
pub deletion: QueueDeletion,
|
||||||
pub consumers: Mutex<HashMap<ConsumerId, Consumer>>,
|
pub consumers: Mutex<HashMap<ConsumerId, Consumer>>,
|
||||||
|
pub event_send: QueueEventSender,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
use amqp_core::error::ProtocolError;
|
use amqp_core::error::ProtocolError;
|
||||||
|
|
||||||
pub mod methods;
|
pub mod methods;
|
||||||
|
mod queue;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, ProtocolError>;
|
type Result<T> = std::result::Result<T, ProtocolError>;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::Result;
|
||||||
use amqp_core::{
|
use amqp_core::{
|
||||||
amqp_todo,
|
amqp_todo,
|
||||||
connection::{Channel, ConnectionEvent},
|
connection::{Channel, ConnectionEvent},
|
||||||
error::{ChannelException, ConException, ProtocolError},
|
error::{ChannelException, ConException},
|
||||||
message::Message,
|
message::Message,
|
||||||
methods::{BasicDeliver, Method},
|
methods::{BasicDeliver, Method},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
use crate::Result;
|
use crate::{queue::QueueTask, Result};
|
||||||
use amqp_core::{
|
use amqp_core::{
|
||||||
amqp_todo,
|
amqp_todo,
|
||||||
connection::Channel,
|
connection::Channel,
|
||||||
methods::{Method, QueueBind, QueueDeclare, QueueDeclareOk},
|
methods::{Method, QueueBind, QueueDeclare, QueueDeclareOk},
|
||||||
queue::{QueueDeletion, QueueId, QueueName, RawQueue},
|
queue::{QueueDeletion, QueueId, QueueInner, QueueName},
|
||||||
GlobalData,
|
GlobalData,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::{atomic::AtomicUsize, Arc};
|
use std::sync::{atomic::AtomicUsize, Arc};
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
use tracing::{info_span, Instrument};
|
||||||
|
|
||||||
pub fn declare(channel: Channel, queue_declare: QueueDeclare) -> Result<Method> {
|
pub fn declare(channel: Channel, queue_declare: QueueDeclare) -> Result<Method> {
|
||||||
let QueueDeclare {
|
let QueueDeclare {
|
||||||
|
|
@ -33,37 +35,41 @@ pub fn declare(channel: Channel, queue_declare: QueueDeclare) -> Result<Method>
|
||||||
amqp_todo!();
|
amqp_todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
let global_data = {
|
let global_data = channel.global_data.clone();
|
||||||
let global_data = channel.global_data.clone();
|
|
||||||
|
|
||||||
let id = QueueId::random();
|
let (event_send, event_recv) = mpsc::channel(10);
|
||||||
let queue = Arc::new(RawQueue {
|
|
||||||
id,
|
|
||||||
name: queue_name.clone(),
|
|
||||||
messages: Mutex::default(),
|
|
||||||
durable,
|
|
||||||
exclusive: exclusive.then(|| channel.id),
|
|
||||||
deletion: if auto_delete {
|
|
||||||
QueueDeletion::Auto(AtomicUsize::default())
|
|
||||||
} else {
|
|
||||||
QueueDeletion::Manual
|
|
||||||
},
|
|
||||||
consumers: Mutex::default(),
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
let id = QueueId::random();
|
||||||
let mut global_data_lock = global_data.lock();
|
let queue = Arc::new(QueueInner {
|
||||||
|
id,
|
||||||
|
name: queue_name.clone(),
|
||||||
|
messages: Mutex::default(),
|
||||||
|
durable,
|
||||||
|
exclusive: exclusive.then(|| channel.id),
|
||||||
|
deletion: if auto_delete {
|
||||||
|
QueueDeletion::Auto(AtomicUsize::default())
|
||||||
|
} else {
|
||||||
|
QueueDeletion::Manual
|
||||||
|
},
|
||||||
|
consumers: Mutex::default(),
|
||||||
|
event_send,
|
||||||
|
});
|
||||||
|
|
||||||
global_data_lock
|
{
|
||||||
.queues
|
let mut global_data_lock = global_data.lock();
|
||||||
.entry(queue_name.clone())
|
|
||||||
.or_insert(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
global_data
|
global_data_lock
|
||||||
};
|
.queues
|
||||||
|
.entry(queue_name.clone())
|
||||||
|
.or_insert_with(|| queue.clone());
|
||||||
|
}
|
||||||
|
|
||||||
bind_queue(global_data, (), queue_name.clone().into_inner())?;
|
bind_queue(global_data.clone(), (), queue_name.clone().into_inner())?;
|
||||||
|
|
||||||
|
let queue_task = QueueTask::new(global_data, event_recv, queue);
|
||||||
|
|
||||||
|
let queue_worker_span = info_span!(parent: None, "queue-worker", %queue_name);
|
||||||
|
tokio::spawn(queue_task.start().instrument(queue_worker_span));
|
||||||
|
|
||||||
Ok(Method::QueueDeclareOk(QueueDeclareOk {
|
Ok(Method::QueueDeclareOk(QueueDeclareOk {
|
||||||
queue: queue_name.to_string(),
|
queue: queue_name.to_string(),
|
||||||
|
|
|
||||||
43
amqp_messaging/src/queue.rs
Normal file
43
amqp_messaging/src/queue.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
use amqp_core::{
|
||||||
|
queue::{Queue, QueueEventReceiver},
|
||||||
|
GlobalData,
|
||||||
|
};
|
||||||
|
use tracing::{debug, info};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct QueueTask {
|
||||||
|
global_data: GlobalData,
|
||||||
|
event_recv: QueueEventReceiver,
|
||||||
|
queue: Queue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueueTask {
|
||||||
|
pub fn new(global_data: GlobalData, event_recv: QueueEventReceiver, queue: Queue) -> Self {
|
||||||
|
Self {
|
||||||
|
global_data,
|
||||||
|
event_recv,
|
||||||
|
queue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start(mut self) {
|
||||||
|
info!("Started queue worker task");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let next_event = self.event_recv.recv().await;
|
||||||
|
|
||||||
|
match next_event {
|
||||||
|
Some(event) => debug!(?event, "Received event"),
|
||||||
|
None => {
|
||||||
|
self.cleanup().await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cleanup(&mut self) {
|
||||||
|
// do stuff or something like that id whatever
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ mod tests;
|
||||||
use crate::connection::TransportConnection;
|
use crate::connection::TransportConnection;
|
||||||
use amqp_core::GlobalData;
|
use amqp_core::GlobalData;
|
||||||
use tokio::net;
|
use tokio::net;
|
||||||
use tracing::{info, info_span, Instrument};
|
use tracing::{info, trace_span, Instrument};
|
||||||
|
|
||||||
pub async fn do_thing_i_guess(global_data: GlobalData) -> anyhow::Result<()> {
|
pub async fn do_thing_i_guess(global_data: GlobalData) -> anyhow::Result<()> {
|
||||||
info!("Binding TCP listener...");
|
info!("Binding TCP listener...");
|
||||||
|
|
@ -26,7 +26,7 @@ pub async fn do_thing_i_guess(global_data: GlobalData) -> anyhow::Result<()> {
|
||||||
let id = rand::random();
|
let id = rand::random();
|
||||||
|
|
||||||
info!(local_addr = ?stream.local_addr(), %id, "Accepted new connection");
|
info!(local_addr = ?stream.local_addr(), %id, "Accepted new connection");
|
||||||
let span = info_span!("client-connection", %id);
|
let span = trace_span!("client-connection", %id);
|
||||||
|
|
||||||
let (method_send, method_recv) = tokio::sync::mpsc::channel(10);
|
let (method_send, method_recv) = tokio::sync::mpsc::channel(10);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue