use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
#[derive(Outgoing, Serialize, Deserialize, PartialEq, Debug)]
struct Order {
id: u64,
}
#[derive(Clone)]
struct CreateOrder {
processed: Arc<AtomicU64>,
}
impl CreateOrder {
fn execute(&self, order: &Order) {
self.processed.fetch_add(order.id, Ordering::Relaxed);
}
}
#[derive(FromRef)]
struct AppState {
create_order: CreateOrder,
}
#[subscriber("orders")]
async fn handle(order: &Order, State(create_order): State<CreateOrder>) -> HandlerOutcome {
create_order.execute(order);
HandlerOutcome::ack()
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let processed = Arc::new(AtomicU64::new(0));
let create_order = CreateOrder {
processed: processed.clone(),
};
let app = RustStream::new(AppInfo::new("orders", "0.1.0"))
.on_startup(move |()| async move {
Ok::<_, std::convert::Infallible>(AppState { create_order })
})
.with_broker(MemoryBroker::new(), |b| {
b.include(handle);
});
let tb = TestApp::start(app).await?;
tb.broker::<MemoryBroker>()
.message(&Order { id: 40 })
.to("orders")
.publish()
.await?;
tb.broker::<MemoryBroker>()
.message(&Order { id: 2 })
.to("orders")
.publish()
.await?;
println!("processed total = {}", processed.load(Ordering::Relaxed));
Ok(())
}