#![cfg_attr(not(test), allow(dead_code, unused_imports))]
mod start_at {
use std::error::Error;
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "audit")]
struct Entry {
id: u64,
}
#[subscriber("audit", start_at(MemoryPosition::start()))]
async fn record(entry: &Entry) -> HandlerOutcome {
tracing::info!(entry.id, "recorded");
HandlerOutcome::ack()
}
fn broker() -> MemoryBroker<Retaining> {
MemoryBroker::retaining(Retention::Messages(nonzero!(64)))
}
fn app(broker: MemoryBroker<Retaining>) -> impl App {
RustStream::new(AppInfo::new("audit", "0.1.0")).with_broker(broker, |b| {
b.include(record);
})
}
#[tokio::test]
async fn the_history_is_replayed() -> Result<(), Box<dyn Error>> {
let broker = broker();
let publisher = broker.publisher();
for id in [1, 2] {
publisher.message(&Entry { id }).publish().await?;
}
let tb = TestApp::start(app(broker)).await?;
tb.settle().await?;
let ids: Vec<u64> = tb
.broker::<MemoryBroker<Retaining>>()
.subscriber("audit")
.received::<Entry>()
.iter()
.map(|entry| entry.id)
.collect();
assert_eq!(ids, [1, 2]);
Ok(())
}
}
mod seek {
use std::error::Error;
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
const POISON: u64 = 999;
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "jobs")]
struct Job {
id: u64,
}
#[subscriber("jobs", start_at(MemoryPosition::start()))]
async fn work(job: &Job, Ctx(seeker): Ctx<SeekHandle>) -> HandlerOutcome {
if job.id == POISON {
if seeker.seek(MemoryPosition::sequence(3)).await.is_err() {
return HandlerOutcome::retry();
}
return HandlerOutcome::ack();
}
tracing::info!(job.id, "processed");
HandlerOutcome::ack()
}
fn app(broker: MemoryBroker<Retaining>) -> impl App {
RustStream::new(AppInfo::new("jobs", "0.1.0")).with_broker(broker, |b| {
b.include(work);
})
}
#[tokio::test]
async fn the_poisoned_region_is_skipped() -> Result<(), Box<dyn Error>> {
let broker = MemoryBroker::retaining(Retention::Messages(nonzero!(64)));
let publisher = broker.publisher();
for id in [1, POISON, 3, 4] {
publisher.message(&Job { id }).publish().await?;
}
let tb = TestApp::start(app(broker)).await?;
tb.settle().await?;
let ids: Vec<u64> = tb
.broker::<MemoryBroker<Retaining>>()
.subscriber("jobs")
.received::<Job>()
.iter()
.map(|job| job.id)
.collect();
assert_eq!(ids, [1, POISON, 4]);
Ok(())
}
}
fn main() {}