mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-14 11:45:02 +01:00
queuing things
This commit is contained in:
parent
2fe3b4b77b
commit
770762b920
16 changed files with 102 additions and 13 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
|
@ -36,6 +36,7 @@ dependencies = [
|
||||||
name = "amqp_core"
|
name = "amqp_core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"amqp_datastructure",
|
||||||
"bytes",
|
"bytes",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
@ -62,11 +63,16 @@ dependencies = [
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "amqp_datastructure"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "amqp_messaging"
|
name = "amqp_messaging"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"amqp_core",
|
"amqp_core",
|
||||||
|
"amqp_datastructure",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
||||||
10
Cargo.toml
10
Cargo.toml
|
|
@ -1,5 +1,13 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [".", "amqp_core", "amqp_dashboard", "amqp_messaging", "amqp_transport","xtask"]
|
members = [
|
||||||
|
".",
|
||||||
|
"amqp_core",
|
||||||
|
"amqp_dashboard",
|
||||||
|
"amqp_datastructure",
|
||||||
|
"amqp_messaging",
|
||||||
|
"amqp_transport",
|
||||||
|
"xtask",
|
||||||
|
]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "amqp"
|
name = "amqp"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
amqp_datastructure = { path = "../amqp_datastructure" }
|
||||||
bytes = "1.1.0"
|
bytes = "1.1.0"
|
||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl Display for QueueName {
|
||||||
pub struct QueueInner {
|
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: amqp_datastructure::MessageQueue<Message>,
|
||||||
pub durable: bool,
|
pub durable: bool,
|
||||||
pub exclusive: Option<ChannelId>,
|
pub exclusive: Option<ChannelId>,
|
||||||
/// Whether the queue will automatically be deleted when no consumers uses it anymore.
|
/// Whether the queue will automatically be deleted when no consumers uses it anymore.
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,12 @@ const DataPage: FC<Props> = ({ prefix }) => {
|
||||||
<h2>Queues</h2>
|
<h2>Queues</h2>
|
||||||
{data ? (
|
{data ? (
|
||||||
<Table
|
<Table
|
||||||
headers={['Queue ID', 'Name', 'Durable']}
|
headers={['Queue ID', 'Name', 'Durable', 'Message Count']}
|
||||||
rows={data.queues.map((queue) => [
|
rows={data.queues.map((queue) => [
|
||||||
queue.id,
|
queue.id,
|
||||||
queue.name,
|
queue.name,
|
||||||
queue.durable ? 'Yes' : 'No',
|
queue.durable ? 'Yes' : 'No',
|
||||||
|
queue.messages,
|
||||||
])}
|
])}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export type Queue = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
durable: boolean;
|
durable: boolean;
|
||||||
|
messages: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Data = {
|
export type Data = {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct Queue {
|
||||||
id: String,
|
id: String,
|
||||||
name: String,
|
name: String,
|
||||||
durable: bool,
|
durable: bool,
|
||||||
|
messages: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_data(global_data: GlobalData) -> impl IntoResponse {
|
async fn get_data(global_data: GlobalData) -> impl IntoResponse {
|
||||||
|
|
@ -106,6 +107,7 @@ async fn get_data(global_data: GlobalData) -> impl IntoResponse {
|
||||||
id: queue.id.to_string(),
|
id: queue.id.to_string(),
|
||||||
name: queue.name.to_string(),
|
name: queue.name.to_string(),
|
||||||
durable: queue.durable,
|
durable: queue.durable,
|
||||||
|
messages: queue.messages.len(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
||||||
8
amqp_datastructure/Cargo.toml
Normal file
8
amqp_datastructure/Cargo.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "amqp_datastructure"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
3
amqp_datastructure/src/lib.rs
Normal file
3
amqp_datastructure/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod message_queue;
|
||||||
|
|
||||||
|
pub use message_queue::MessageQueue;
|
||||||
57
amqp_datastructure/src/message_queue.rs
Normal file
57
amqp_datastructure/src/message_queue.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
// using std::sync::Mutex because it's only temporary anyways
|
||||||
|
use std::{
|
||||||
|
collections::VecDeque,
|
||||||
|
fmt::{Debug, Formatter},
|
||||||
|
sync::Mutex,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The data structure behind the message queue.
|
||||||
|
///
|
||||||
|
/// Needs to support:
|
||||||
|
/// * concurrent access
|
||||||
|
/// * priority
|
||||||
|
///
|
||||||
|
/// Currently supports
|
||||||
|
/// * mutex lol
|
||||||
|
// todo: see above
|
||||||
|
pub struct MessageQueue<T> {
|
||||||
|
deque: Mutex<VecDeque<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MessageQueue<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
deque: Mutex::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(&self, message: T) {
|
||||||
|
let mut lock = self.deque.lock().unwrap();
|
||||||
|
lock.push_back(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_get(&self) -> Option<T> {
|
||||||
|
let mut lock = self.deque.lock().unwrap();
|
||||||
|
lock.pop_front()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.deque.lock().unwrap().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for MessageQueue<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug> Debug for MessageQueue<T> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("MessageQueue").finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
amqp_core = { path = "../amqp_core" }
|
amqp_core = { path = "../amqp_core" }
|
||||||
|
amqp_datastructure = { path = "../amqp_datastructure" }
|
||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
tracing = "0.1.31"
|
tracing = "0.1.31"
|
||||||
tokio = { version = "1.17.0", features = ["full"] }
|
tokio = { version = "1.17.0", features = ["full"] }
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,10 @@ mod queue;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use amqp_core::{amqp_todo, connection::Channel, message::Message, methods::Method};
|
use amqp_core::{amqp_todo, connection::Channel, message::Message, methods::Method};
|
||||||
use tracing::{error, info};
|
use tracing::info;
|
||||||
|
|
||||||
pub fn handle_basic_publish(channel_handle: Channel, message: Message) {
|
pub fn handle_basic_publish(channel_handle: Channel, message: Message) -> Result<()> {
|
||||||
match publish::publish(channel_handle, message) {
|
publish::publish(channel_handle, message)
|
||||||
Ok(()) => {}
|
|
||||||
Err(err) => error!(%err, "publish error occurred"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_method(channel_handle: Channel, method: Method) -> Result<Method> {
|
pub async fn handle_method(channel_handle: Channel, method: Method) -> Result<Method> {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ pub fn declare(channel: Channel, queue_declare: QueueDeclare) -> Result<Method>
|
||||||
let queue = Arc::new(QueueInner {
|
let queue = Arc::new(QueueInner {
|
||||||
id,
|
id,
|
||||||
name: queue_name.clone(),
|
name: queue_name.clone(),
|
||||||
messages: Mutex::default(),
|
messages: amqp_datastructure::MessageQueue::new(),
|
||||||
durable,
|
durable,
|
||||||
exclusive: exclusive.then(|| channel.id),
|
exclusive: exclusive.then(|| channel.id),
|
||||||
deletion: if auto_delete {
|
deletion: if auto_delete {
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,9 @@ impl QueueTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self), fields(name = self.show_name()), level = "trace")]
|
#[tracing::instrument(skip(self), fields(name = self.show_name()), level = "trace")]
|
||||||
async fn queue_message(&mut self, _message: Message) {}
|
async fn queue_message(&mut self, message: Message) {
|
||||||
|
self.queue.messages.append(message);
|
||||||
|
}
|
||||||
|
|
||||||
async fn cleanup(&mut self) {
|
async fn cleanup(&mut self) {
|
||||||
// do stuff or something like that id whatever
|
// do stuff or something like that id whatever
|
||||||
|
|
|
||||||
|
|
@ -498,7 +498,7 @@ impl TransportConnection {
|
||||||
|
|
||||||
let channel = self.channels.get(&channel).ok_or(ConException::Todo)?;
|
let channel = self.channels.get(&channel).ok_or(ConException::Todo)?;
|
||||||
|
|
||||||
amqp_messaging::methods::handle_basic_publish(channel.global_chan.clone(), message);
|
amqp_messaging::methods::handle_basic_publish(channel.global_chan.clone(), message)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ConException::Todo.into())
|
Err(ConException::Todo.into())
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ import { connectAmqp } from './utils/utils.js';
|
||||||
const connection = await connectAmqp();
|
const connection = await connectAmqp();
|
||||||
const channel = await connection.createChannel();
|
const channel = await connection.createChannel();
|
||||||
|
|
||||||
channel.publish('exchange-1', 'queue-1', Buffer.from('hello'));
|
await channel.assertQueue('send-queue-352');
|
||||||
|
|
||||||
|
channel.publish('', 'send-queue-352', Buffer.from('hello'));
|
||||||
|
|
||||||
console.log('Published message');
|
console.log('Published message');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue