#![cfg_attr(not(test), allow(dead_code, unused_imports))]
mod batch {
use std::error::Error;
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "orders")]
struct Order {
id: u64,
}
#[subscriber("orders")]
async fn store(orders: &[Order]) -> HandlerOutcome {
tracing::info!(count = orders.len(), "stored in one round-trip");
HandlerOutcome::ack()
}
fn app(broker: MemoryBroker) -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(broker, |b| {
b.include(store.batch(nonzero!(64)));
})
}
#[tokio::test]
async fn three_orders_arrive_in_one_call() -> Result<(), Box<dyn Error>> {
let broker = MemoryBroker::new();
let publisher = broker.publisher();
let tb = TestApp::start(app(broker)).await?;
for id in [1, 2, 3] {
publisher.message(&Order { id }).publish().await?;
}
tb.settle().await?;
tb.broker::<MemoryBroker>()
.subscriber("orders")
.assert_called_once()
.assert_batch_sizes(&[3])
.settled(HandlerOutcome::ack());
Ok(())
}
}
mod per_element {
use std::error::Error;
use std::time::Duration;
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
const RECHECK: Duration = Duration::from_secs(30);
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "payments")]
struct Payment {
id: u64,
cleared: bool,
}
#[subscriber("payments")]
async fn reconcile(payments: &[Payment]) -> Vec<HandlerOutcome> {
payments
.iter()
.map(|payment| {
if payment.cleared {
HandlerOutcome::ack()
} else {
HandlerOutcome::retry_after(RECHECK)
}
})
.collect()
}
fn app(broker: MemoryBroker) -> impl App {
RustStream::new(AppInfo::new("payments", "0.1.0")).with_broker(broker, |b| {
b.include(reconcile.batch(nonzero!(64)));
})
}
#[tokio::test(start_paused = true)]
async fn only_the_uncleared_payment_comes_back() -> Result<(), Box<dyn Error>> {
let broker = MemoryBroker::new();
let publisher = broker.publisher();
let tb = TestApp::start(app(broker)).await?;
for (id, cleared) in [(1, true), (2, false), (3, true)] {
publisher
.message(&Payment { id, cleared })
.publish()
.await?;
}
tb.settle().await?;
tb.advance(RECHECK).await?;
let ids: Vec<Vec<u64>> = tb
.broker::<MemoryBroker>()
.subscriber("payments")
.batches::<Payment>()
.iter()
.map(|batch| batch.iter().map(|payment| payment.id).collect())
.collect();
assert_eq!(ids, [vec![1, 2, 3], vec![2]]);
Ok(())
}
}
fn main() {}