lapin-test/src/main.rs
2024-01-28 18:29:54 +11:00

102 lines
3.2 KiB
Rust

#![feature(async_closure)]
#![feature(btree_cursors)]
#![feature(let_chains)]
mod ack;
mod processor;
pub mod range_map;
use std::time::Duration;
use anyhow::{anyhow, Result};
use lapin::{options::BasicPublishOptions, publisher_confirm::Confirmation, topology::{BindingDefinition, ExchangeDefinition, QueueDefinition, TopologyDefinition}, types::FieldTable, BasicProperties, Channel, Connection, ConnectionProperties};
use rand::{Rng, thread_rng};
use serde::{Deserialize, Serialize};
use tokio::{signal, time::sleep};
use crate::processor::Processor;
static QUEUE_COUNT: usize = 10;
static SEND_COUNT: usize = 100_000;
#[tokio::main]
async fn main() -> Result<()> {
let quit_signal = signal::ctrl_c();
let conn = broker_connect().await?;
let _ = conn.restore(TopologyDefinition {
exchanges: vec![
ExchangeDefinition { name: "hello".into(), kind: None, options: None, arguments: None, bindings: vec![] },
],
queues: (0..QUEUE_COUNT).map(|i|
QueueDefinition { name: format!("hello-{}", i).into(), options: None, arguments: None,
bindings: vec![
BindingDefinition {
source: "hello".into(),
routing_key: "".into(),
arguments: FieldTable::default(),
},
]
}
).collect(),
channels: vec![],
}).await?;
tokio::try_join!(
tokio::spawn(async {
let mut proc = Processor::new(broker_connect().await?, 65_535).await?;
for i in 0..QUEUE_COUNT {
proc.listen(&format!("hello-{}", i), &format!("processor-{}", i), move |data| process(data, i)).await?;
}
quit_signal.await.unwrap();
proc.shutdown().await
}),
tokio::spawn(async {
let chan = conn.create_channel().await?;
sender(conn, chan).await
}),
)?;
Ok(())
}
async fn broker_connect() -> lapin::Result<Connection> {
Connection::connect(
"amqp://localhost",
ConnectionProperties::default()
.with_executor(tokio_executor_trait::Tokio::current())
.with_reactor(tokio_reactor_trait::Tokio),
).await
}
#[derive(Serialize, Deserialize)]
struct Test { int: usize }
async fn sender(conn: Connection, chan: Channel) -> lapin::Result<()> {
for int in 0..SEND_COUNT {
if int % 1000 == 0 { println!("Sending {}", int) };
let payload = Test { int };
let confirm = chan.basic_publish(
"hello",
"",
BasicPublishOptions::default(),
&serde_json::to_vec(&payload).unwrap(),
BasicProperties::default(),
).await?.await?;
assert_eq!(confirm, Confirmation::NotRequested);
}
conn.close(0, "").await?;
println!("Done sending");
Ok(())
}
async fn process(_test: Test, _i: usize) -> Result<()> {
let (dur, fail) = {
let mut rng = thread_rng();
(Duration::from_millis(rng.gen_range(1000..10000)), rng.gen_bool(0.01))
};
sleep(dur).await;
//if fail { println!("{} Fail {} {:?}", _i, _test.int, dur); }
if fail { Err(anyhow!("oops")) } else { Ok(()) }
}