use ruststream::memory::MemorySource;
use ruststream::runtime::HandlerOutcome;
use ruststream::subscriber;
use crate::domain::{Cancellation, Confirmation, Order, Repository};
#[subscriber(MemorySource::new("orders"), reply("confirmations"))]
pub(crate) async fn confirm(
order: &Order,
ctx: &mut Context<'_, (), Repository>,
) -> Result<Confirmation, HandlerOutcome> {
let repo = ctx.state();
tracing::debug!(
order = order.id,
customer = %order.customer,
item = %order.item,
"confirming order"
);
match repo.record_order(order.id).await {
Ok(()) => Ok(Confirmation {
order_id: order.id,
accepted: order.quantity > 0,
}),
Err(e) if e.is_transient() => {
tracing::warn!(order = order.id, "store busy, asking for redelivery");
Err(HandlerOutcome::retry())
}
Err(e) => {
tracing::error!(order = order.id, error = %e, "dropping order");
Err(HandlerOutcome::drop())
}
}
}
#[subscriber("cancellations")]
pub(crate) async fn on_cancel(
cancel: &Cancellation,
ctx: &mut Context<'_, (), Repository>,
) -> HandlerOutcome {
let repo = ctx.state();
match repo.cancel(cancel.order_id).await {
Err(e) if e.is_transient() => HandlerOutcome::retry(),
_ => HandlerOutcome::ack(),
}
}