Skip to main content

OutboxStore

Trait OutboxStore 

Source
pub trait OutboxStore: Send + Sync {
    // Required methods
    async fn enqueue(
        &self,
        messages: &[OutboxMessage],
    ) -> Result<(), EngineError>;
    async fn pending(
        &self,
        limit: usize,
        now: OffsetDateTime,
    ) -> Result<Vec<OutboxMessage>, EngineError>;
    async fn acknowledge(&self, id: OutboxMessageId) -> Result<(), EngineError>;
    async fn reschedule(
        &self,
        id: OutboxMessageId,
        deliver_after: OffsetDateTime,
    ) -> Result<(), EngineError>;
    async fn len(&self) -> Result<usize, EngineError>;

    // Provided methods
    async fn pending_now(
        &self,
        limit: usize,
    ) -> Result<Vec<OutboxMessage>, EngineError> { ... }
    async fn is_empty(&self) -> Result<bool, EngineError> { ... }
}
Expand description

Storage contract for outbox messages.

§Atomicity requirement

In production deployments, calls to OutboxStore::enqueue MUST be atomic with the corresponding EventStore::append — both writes MUST succeed or both MUST fail. Implement this by sharing the same database transaction across both operations.

§Delivery worker contract

The delivery worker loop should:

  1. Call OutboxStore::pending_now to retrieve ready messages.
  2. Attempt delivery to the AS4 endpoint.
  3. On success: call OutboxStore::acknowledge to remove the message.
  4. On transient failure: call OutboxStore::reschedule with an exponential back-off delay.

§Blanket Arc implementation

Arc<S> implements OutboxStore whenever S: OutboxStore, so you can share a store across a delivery worker and command handlers without additional wrapper types.

Required Methods§

Source

async fn enqueue(&self, messages: &[OutboxMessage]) -> Result<(), EngineError>

Persist messages durably, ready for delivery.

In a persistent backend this MUST be called within the same transaction as the event append.

§Errors

Returns EngineError::Outbox on storage failure.

Source

async fn pending( &self, limit: usize, now: OffsetDateTime, ) -> Result<Vec<OutboxMessage>, EngineError>

Return up to limit messages ready for delivery as of now.

A message is ready when deliver_after is None or <= now. Results are ordered oldest-first by created_at.

§Errors

Returns EngineError::Outbox on storage failure.

Source

async fn acknowledge(&self, id: OutboxMessageId) -> Result<(), EngineError>

Remove a message from the outbox after successful delivery.

Calling this with an unknown id is a no-op.

§Errors

Returns EngineError::Outbox on storage failure.

Source

async fn reschedule( &self, id: OutboxMessageId, deliver_after: OffsetDateTime, ) -> Result<(), EngineError>

Reschedule a message for a future delivery attempt.

Implementations MUST increment attempt_count on the stored record. Calling this with an unknown id is a no-op.

§Errors

Returns EngineError::Outbox on storage failure.

Source

async fn len(&self) -> Result<usize, EngineError>

Return the total number of messages currently in the outbox.

§Errors

Returns EngineError::Outbox on storage failure.

Provided Methods§

Source

async fn pending_now( &self, limit: usize, ) -> Result<Vec<OutboxMessage>, EngineError>

Return up to limit messages ready for delivery right now.

Convenience wrapper around OutboxStore::pending that uses OffsetDateTime::now_utc() as the reference time.

§Errors

Returns EngineError::Outbox on storage failure.

Source

async fn is_empty(&self) -> Result<bool, EngineError>

Return true when the outbox contains no messages.

§Errors

Returns EngineError::Outbox on storage failure.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<S: OutboxStore> OutboxStore for Arc<S>

Source§

async fn enqueue(&self, messages: &[OutboxMessage]) -> Result<(), EngineError>

Source§

async fn pending( &self, limit: usize, now: OffsetDateTime, ) -> Result<Vec<OutboxMessage>, EngineError>

Source§

async fn acknowledge(&self, id: OutboxMessageId) -> Result<(), EngineError>

Source§

async fn reschedule( &self, id: OutboxMessageId, deliver_after: OffsetDateTime, ) -> Result<(), EngineError>

Source§

async fn len(&self) -> Result<usize, EngineError>

Implementors§