pub struct RabbitMqDelivery { /* private fields */ }Expand description
One RabbitMQ message, decoded into an Envelope.
Exactly one of ack, retry,
defer or dead_letter must be
called; the trait consumes the delivery so the compiler enforces “at most
once”, and an un-acked delivery is redelivered by the broker when the
consumer channel closes.
retry, defer and
dead_letter publish before they ack, and
propagate the publish error without acking, so a failure leaves the original
message unacknowledged for the broker to redeliver rather than dropping the
job. Because publishes are mandatory, a missing q.retry / q.dead
counts as a failure. A hold queue cannot be missing: defer declares it
itself, immediately before publishing, but that declaration can be
refused, and defer says what happens then.
When
declare_dead_letter_queues
is false this backend does not own q.dead, so
dead_letter rejects the message (requeue = false)
instead of publishing to it, and logs why.
Trait Implementations§
Source§impl Debug for RabbitMqDelivery
impl Debug for RabbitMqDelivery
Source§impl Delivery for RabbitMqDelivery
impl Delivery for RabbitMqDelivery
Source§fn defer<'async_trait>(
self: Box<Self>,
next: Envelope,
delay: Duration,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
fn defer<'async_trait>(
self: Box<Self>,
next: Envelope,
delay: Duration,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
Publish first, ack second, the same rule as retry.
next is written into a hold queue (declared on the spot, mandatory,
waited on for a publisher confirm) and only once the broker has taken
responsibility for it is the original acked. If the publish fails the ?
returns before the ack, so the original stays unacknowledged and the
broker redelivers it, so the job is retried rather than silently dropped.
The reverse order would lose a job on any broker hiccup between the two.
Three things count as that failure, and all three leave the original unacked (the worker counts a settle failure and the broker redelivers the job when the consumer channel closes):
- the hold queue exists with different arguments, so the declaration is
refused with
PRECONDITION_FAILED. The declaration runs on its own channel, so concurrent publishes are untouched; next.queuewas never declared through this backend, so the hold queue’s durability and dead-letter target are unknown (Error::UnknownQueue);delayis longer thanMAX_DEFERRAL_MS(~24.8 days), which is refused rather than shortened, because a deferral is never released early.
A caveat on “ahead of the backlog”: a consumer with prefetch N is
already holding up to N messages of that backlog, and the returning
deferral cannot overtake those. It is first among what is still on the
queue.
Source§fn ack<'async_trait>(
self: Box<Self>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
fn ack<'async_trait>(
self: Box<Self>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
Source§fn dead_letter<'life0, 'async_trait>(
self: Box<Self>,
reason: &'life0 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn dead_letter<'life0, 'async_trait>(
self: Box<Self>,
reason: &'life0 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn retry<'async_trait>(
self: Box<Self>,
next: Envelope,
delay: Duration,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
fn retry<'async_trait>(
self: Box<Self>,
next: Envelope,
delay: Duration,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
next (already attempt + 1) to be redelivered
after delay. Implementations must ack the original after the retry is
durably scheduled so no message is lost.