Skip to main content

Module outbox

Module outbox 

Source
Expand description

Transactional-outbox drainer runtime.

Entities declared with #[entity(events(outbox))] enqueue their lifecycle events into the entity_outbox table inside the same transaction as the write. This module delivers those rows:

use entity_core::outbox::{OutboxDrainer, OutboxHandler, OutboxRow};

struct Notifier;

#[async_trait::async_trait]
impl OutboxHandler for Notifier {
    type Error = anyhow::Error;

    async fn handle(&self, row: &OutboxRow) -> Result<(), Self::Error> {
        send_somewhere(&row.entity, &row.payload).await
    }
}

OutboxDrainer::new(pool, Notifier)
    .run()   // polls until the task is aborted
    .await;

§Delivery Semantics

  • Rows are claimed with FOR UPDATE SKIP LOCKED, so multiple drainers cooperate without double delivery.
  • A successful handle marks the row processed; a failure schedules a retry with exponential backoff (base_backoff * 2^attempts).
  • After max_attempts failures the row stays unprocessed with next_attempt_at in the far future — inspect and repair manually.
  • At-least-once delivery: handlers must be idempotent.

Structs§

OutboxDrainer
Polling drainer delivering entity_outbox rows to a handler.
OutboxRow
One claimed outbox row handed to the OutboxHandler.

Enums§

OutboxAction
Outcome of handling one claimed outbox row.

Traits§

OutboxHandler
User-provided delivery target for outbox rows.

Functions§

backoff_delay
Compute the retry delay for a row that has already failed attempts times.
process_rows
Run the handler over claimed rows and decide per-row follow-up.