mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-16 20:55:03 +01:00
consume prototype
This commit is contained in:
parent
beb2187cd6
commit
93ce632b5d
21 changed files with 328 additions and 108 deletions
|
|
@ -10,3 +10,5 @@ amqp_core = { path = "../amqp_core" }
|
|||
parking_lot = "0.12.0"
|
||||
tracing = "0.1.31"
|
||||
tokio = { version = "1.17.0", features = ["full"] }
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use amqp_core::error::ProtocolError;
|
||||
|
||||
pub mod methods;
|
||||
|
||||
type Result<T> = std::result::Result<T, ProtocolError>;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,56 @@
|
|||
use crate::Result;
|
||||
use amqp_core::amqp_todo;
|
||||
use amqp_core::connection::ChannelHandle;
|
||||
use amqp_core::error::ProtocolError;
|
||||
use amqp_core::methods::{BasicConsume, Method};
|
||||
use amqp_core::consumer::{Consumer, ConsumerId};
|
||||
use amqp_core::error::{ChannelException};
|
||||
use amqp_core::methods::{BasicConsume, BasicConsumeOk, Method};
|
||||
use std::sync::Arc;
|
||||
use tracing::info;
|
||||
|
||||
pub async fn consume(
|
||||
channel_handle: ChannelHandle,
|
||||
_basic_consume: BasicConsume,
|
||||
) -> Result<Method, ProtocolError> {
|
||||
let _channel = channel_handle.lock();
|
||||
pub fn consume(channel_handle: ChannelHandle, basic_consume: BasicConsume) -> Result<Method> {
|
||||
let BasicConsume {
|
||||
queue: queue_name,
|
||||
consumer_tag,
|
||||
no_local,
|
||||
no_ack,
|
||||
exclusive,
|
||||
no_wait,
|
||||
..
|
||||
} = basic_consume;
|
||||
|
||||
amqp_todo!()
|
||||
if no_wait || no_local || exclusive || no_ack {
|
||||
amqp_todo!();
|
||||
}
|
||||
|
||||
let global_data = {
|
||||
let channel = channel_handle.lock();
|
||||
channel.global_data.clone()
|
||||
};
|
||||
|
||||
let consumer_tag = if consumer_tag.is_empty() {
|
||||
amqp_core::random_uuid().to_string()
|
||||
} else {
|
||||
consumer_tag
|
||||
};
|
||||
|
||||
let mut global_data = global_data.lock();
|
||||
|
||||
let consumer = Consumer {
|
||||
id: ConsumerId::random(),
|
||||
tag: consumer_tag.clone(),
|
||||
channel: Arc::clone(&channel_handle),
|
||||
};
|
||||
|
||||
let queue = global_data
|
||||
.queues
|
||||
.get_mut(queue_name.as_str())
|
||||
.ok_or(ChannelException::NotFound)?;
|
||||
|
||||
queue.consumers.lock().push(consumer);
|
||||
|
||||
info!(%queue_name, %consumer_tag, "Consumer started consuming");
|
||||
|
||||
let method = Method::BasicConsumeOk(BasicConsumeOk { consumer_tag });
|
||||
|
||||
Ok(method)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,22 @@
|
|||
mod consume;
|
||||
mod publish;
|
||||
mod queue;
|
||||
|
||||
use crate::Result;
|
||||
use amqp_core::amqp_todo;
|
||||
use amqp_core::connection::ChannelHandle;
|
||||
use amqp_core::error::ProtocolError;
|
||||
use amqp_core::message::Message;
|
||||
use amqp_core::methods::Method;
|
||||
use tracing::info;
|
||||
use tracing::{error, info};
|
||||
|
||||
pub async fn handle_basic_publish(_channel_handle: ChannelHandle, message: Message) {
|
||||
info!(
|
||||
?message,
|
||||
"Someone has summoned the almighty Basic.Publish handler"
|
||||
);
|
||||
pub async fn handle_basic_publish(channel_handle: ChannelHandle, message: Message) {
|
||||
match publish::publish(channel_handle, message).await {
|
||||
Ok(()) => {}
|
||||
Err(err) => error!(%err, "publish error occurred"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_method(
|
||||
channel_handle: ChannelHandle,
|
||||
method: Method,
|
||||
) -> Result<Method, ProtocolError> {
|
||||
pub async fn handle_method(channel_handle: ChannelHandle, method: Method) -> Result<Method> {
|
||||
info!(?method, "Handling method");
|
||||
|
||||
let response = match method {
|
||||
|
|
@ -26,9 +24,7 @@ pub async fn handle_method(
|
|||
Method::ExchangeDeclareOk(_) => amqp_todo!(),
|
||||
Method::ExchangeDelete(_) => amqp_todo!(),
|
||||
Method::ExchangeDeleteOk(_) => amqp_todo!(),
|
||||
Method::QueueDeclare(queue_declare) => {
|
||||
queue::declare(channel_handle, queue_declare).await?
|
||||
}
|
||||
Method::QueueDeclare(queue_declare) => queue::declare(channel_handle, queue_declare)?,
|
||||
Method::QueueDeclareOk { .. } => amqp_todo!(),
|
||||
Method::QueueBind(queue_bind) => queue::bind(channel_handle, queue_bind).await?,
|
||||
Method::QueueBindOk(_) => amqp_todo!(),
|
||||
|
|
@ -40,7 +36,7 @@ pub async fn handle_method(
|
|||
Method::QueueDeleteOk { .. } => amqp_todo!(),
|
||||
Method::BasicQos { .. } => amqp_todo!(),
|
||||
Method::BasicQosOk(_) => amqp_todo!(),
|
||||
Method::BasicConsume(consume) => consume::consume(channel_handle, consume).await?,
|
||||
Method::BasicConsume(consume) => consume::consume(channel_handle, consume)?,
|
||||
Method::BasicConsumeOk { .. } => amqp_todo!(),
|
||||
Method::BasicCancel { .. } => amqp_todo!(),
|
||||
Method::BasicCancelOk { .. } => amqp_todo!(),
|
||||
|
|
|
|||
52
amqp_messaging/src/methods/publish.rs
Normal file
52
amqp_messaging/src/methods/publish.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
use crate::Result;
|
||||
use amqp_core::amqp_todo;
|
||||
use amqp_core::connection::{ChannelHandle, QueuedMethod};
|
||||
use amqp_core::error::ChannelException;
|
||||
use amqp_core::message::Message;
|
||||
use amqp_core::methods::{BasicPublish, Method};
|
||||
use tracing::info;
|
||||
|
||||
pub async fn publish(channel_handle: ChannelHandle, message: Message) -> Result<()> {
|
||||
info!(?message, "Publishing message");
|
||||
|
||||
let global_data = channel_handle.lock().global_data.clone();
|
||||
|
||||
let routing = &message.routing;
|
||||
|
||||
if !routing.exchange.is_empty() {
|
||||
amqp_todo!();
|
||||
}
|
||||
|
||||
let mut global_data = global_data.lock();
|
||||
|
||||
let queue = global_data
|
||||
.queues
|
||||
.get_mut(routing.routing_key.as_str())
|
||||
.ok_or(ChannelException::NotFound)?;
|
||||
|
||||
{
|
||||
// todo: we just send it to the consumer directly and ignore it if the consumer doesn't exist
|
||||
// consuming is hard, but this should work *for now*
|
||||
let consumers = queue.consumers.lock();
|
||||
if let Some(consumer) = consumers.first() {
|
||||
let method = Method::BasicPublish(BasicPublish {
|
||||
reserved_1: 0,
|
||||
exchange: routing.exchange.clone(),
|
||||
routing_key: routing.routing_key.clone(),
|
||||
mandatory: false,
|
||||
immediate: false,
|
||||
});
|
||||
|
||||
consumer
|
||||
.channel
|
||||
.lock()
|
||||
.queue_method(QueuedMethod::WithContent(
|
||||
method,
|
||||
message.header.clone(),
|
||||
message.content.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
use amqp_core::connection::ChannelHandle;
|
||||
use amqp_core::error::ProtocolError;
|
||||
use amqp_core::methods::{Method, QueueBind, QueueDeclare, QueueDeclareOk};
|
||||
use amqp_core::queue::{QueueDeletion, QueueId, QueueName, RawQueue};
|
||||
use amqp_core::{amqp_todo, GlobalData};
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
use crate::Result;
|
||||
|
||||
pub async fn declare(
|
||||
pub fn declare(
|
||||
channel_handle: ChannelHandle,
|
||||
queue_declare: QueueDeclare,
|
||||
) -> Result<Method, ProtocolError> {
|
||||
) -> Result<Method> {
|
||||
let QueueDeclare {
|
||||
queue: queue_name,
|
||||
passive,
|
||||
|
|
@ -28,7 +28,9 @@ pub async fn declare(
|
|||
amqp_todo!();
|
||||
}
|
||||
|
||||
if passive || no_wait || durable {
|
||||
// todo: durable is technically spec-compliant, the spec doesn't really require it, but it's a todo
|
||||
// not checked here because it's the default for amqplib which is annoying
|
||||
if passive || no_wait {
|
||||
amqp_todo!();
|
||||
}
|
||||
|
||||
|
|
@ -48,6 +50,7 @@ pub async fn declare(
|
|||
} else {
|
||||
QueueDeletion::Manual
|
||||
},
|
||||
consumers: Mutex::default(),
|
||||
});
|
||||
|
||||
{
|
||||
|
|
@ -58,7 +61,7 @@ pub async fn declare(
|
|||
global_data
|
||||
};
|
||||
|
||||
bind_queue(global_data, (), queue_name.clone().into_inner()).await?;
|
||||
bind_queue(global_data, (), queue_name.clone().into_inner())?;
|
||||
|
||||
Ok(Method::QueueDeclareOk(QueueDeclareOk {
|
||||
queue: queue_name.to_string(),
|
||||
|
|
@ -70,15 +73,15 @@ pub async fn declare(
|
|||
pub async fn bind(
|
||||
_channel_handle: ChannelHandle,
|
||||
_queue_bind: QueueBind,
|
||||
) -> Result<Method, ProtocolError> {
|
||||
) -> Result<Method> {
|
||||
amqp_todo!();
|
||||
}
|
||||
|
||||
async fn bind_queue(
|
||||
fn bind_queue(
|
||||
global_data: GlobalData,
|
||||
_exchange: (),
|
||||
routing_key: Arc<str>,
|
||||
) -> Result<(), ProtocolError> {
|
||||
) -> Result<()> {
|
||||
let mut global_data = global_data.lock();
|
||||
|
||||
// todo: don't
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue