feat: worker relays outbox to nats
This commit is contained in:
48
crates/bootstrap/src/outbox_relay.rs
Normal file
48
crates/bootstrap/src/outbox_relay.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
//! Moves outbox rows onto the message bus. The worker runs it when the bus is
|
||||
//! not the outbox itself (`EVENT_BUS_BACKEND=nats`).
|
||||
//!
|
||||
//! Rows are claimed by the SQLite queue's own atomic claim, so a row is only
|
||||
//! ever relayed by one claimant and failures take the queue's existing
|
||||
//! backoff and dead-letter path. A row is marked done only after the sink
|
||||
//! reports the bus accepted it; a crash in between re-relays the row, and the
|
||||
//! bus de-duplicates on the event id.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::{
|
||||
events::EventEnvelope,
|
||||
ports::{EventConsumer, EventRelaySink},
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
pub fn spawn(source: Arc<dyn EventConsumer>, sink: Arc<dyn EventRelaySink>) -> JoinHandle<()> {
|
||||
tokio::spawn(async move {
|
||||
let mut rows = source.consume();
|
||||
while let Some(next) = rows.next().await {
|
||||
match next {
|
||||
Ok(envelope) => relay_envelope(envelope, sink.as_ref()).await,
|
||||
// A row that cannot even be decoded stays claimed; there is
|
||||
// no handle to settle it with.
|
||||
Err(e) => tracing::error!("outbox relay: undecodable row: {e}"),
|
||||
}
|
||||
}
|
||||
tracing::warn!("outbox relay: source closed, relay stopped");
|
||||
})
|
||||
}
|
||||
|
||||
async fn relay_envelope(envelope: EventEnvelope, sink: &dyn EventRelaySink) {
|
||||
match sink.relay(envelope.id(), &envelope.event).await {
|
||||
Ok(()) => {
|
||||
if let Err(e) = envelope.ack().await {
|
||||
tracing::error!("outbox relay: published but could not mark done: {e}");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!("outbox relay: publish failed, will retry: {e}");
|
||||
if let Err(e) = envelope.nack().await {
|
||||
tracing::error!("outbox relay: could not nack: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user