pub trait IncomingMessage: Send + Sync {
// Required methods
fn payload(&self) -> &[u8] ⓘ;
fn headers(&self) -> &HeaderMap;
fn ack(self) -> impl Future<Output = Result<(), AckError>> + Send;
fn nack(
self,
requeue: bool,
) -> impl Future<Output = Result<(), AckError>> + Send;
// Provided methods
fn partition_key(&self) -> Option<&[u8]> { ... }
fn redelivery_count(&self) -> Option<u64> { ... }
fn supports_nack_after(&self) -> bool { ... }
fn nack_after(
self,
delay: Duration,
) -> impl Future<Output = Result<(), AckError>> + Send
where Self: Sized { ... }
}Expand description
A message delivered by a Subscriber.
Consumers inspect payload and headers, then must call either ack or nack
exactly once. The consuming self receiver in those methods makes double acknowledgement
a compile-time error.
§Cancel safety
Implementations must document whether ack and nack are cancel-safe. If a future is
dropped before completion, the broker may treat the message as still pending, leading to
redelivery once the visibility timeout expires.
Required Methods§
Provided Methods§
Sourcefn partition_key(&self) -> Option<&[u8]>
fn partition_key(&self) -> Option<&[u8]>
Returns the routing key the broker partitioned this message by, or None when the
message carries no key.
Defaulted to None so existing implementations keep compiling. Brokers whose messages
implement the Partitioned capability override this to return the
same key, which lets the runtime preserve per-key ordering in keyed worker lanes
(workers(n, by_key)) without a Partitioned bound on every dispatch path.
Sourcefn redelivery_count(&self) -> Option<u64>
fn redelivery_count(&self) -> Option<u64>
How many times the broker has delivered this message, counting this delivery. None
where the transport counts nothing.
Defaulted to None, which is the honest answer for a transport with no counter of its
own; the runtime then counts with its own
RETRY_COUNT_HEADER alone. A broker whose
deliveries carry a count reports it here - JetStream’s num_delivered, a claimed Redis
stream entry’s delivery count, Pulsar’s redelivery_count, SQS’s
ApproximateReceiveCount, Pub/Sub’s delivery_attempt, AMQP 1.0’s delivery-count - so
that a registration’s max_attempts(..) cap counts the broker’s own redeliveries rather
than only the copies this process published. The first delivery of a message answers 1.
Where the transport counts, this count is the only one a cap reads: the framework’s header is never mixed in, and a copy your crate republishes starts the transport’s count afresh. A delay or a requeue the count does not grow on is the broker’s behaviour to document, not something to work around by adding the header back.
§Examples
use ruststream::{AckError, HeaderMap, IncomingMessage};
struct Delivered {
payload: Vec<u8>,
headers: HeaderMap,
delivered: u64,
}
impl IncomingMessage for Delivered {
fn payload(&self) -> &[u8] {
&self.payload
}
fn headers(&self) -> &HeaderMap {
&self.headers
}
fn redelivery_count(&self) -> Option<u64> {
Some(self.delivered)
}
async fn ack(self) -> Result<(), AckError> {
Ok(())
}
async fn nack(self, _requeue: bool) -> Result<(), AckError> {
Ok(())
}
}Sourcefn supports_nack_after(&self) -> bool
fn supports_nack_after(&self) -> bool
Reports whether this transport can honor nack_after natively.
Defaulted to false: a transport without native delayed redelivery cannot hold a
message back for delay on its own. The runtime reads this BEFORE settling a
retry_after outcome: when it returns true
the runtime calls nack_after and trusts the broker timer; when it
returns false the runtime applies its broker-agnostic deferred-republish fallback
instead, so the delay is never silently dropped. Brokers with native delayed redelivery
(JetStream NAK with delay, a durable delayed queue) override this to true and
override nack_after.
§Examples
use ruststream::{AckError, HeaderMap, IncomingMessage};
struct CoreMessage {
payload: Vec<u8>,
headers: HeaderMap,
}
impl IncomingMessage for CoreMessage {
fn payload(&self) -> &[u8] {
&self.payload
}
fn headers(&self) -> &HeaderMap {
&self.headers
}
async fn ack(self) -> Result<(), AckError> {
Ok(())
}
async fn nack(self, _requeue: bool) -> Result<(), AckError> {
Ok(())
}
// No native delayed redelivery: keep the default, opting into the runtime fallback.
}Sourcefn nack_after(
self,
delay: Duration,
) -> impl Future<Output = Result<(), AckError>> + Sendwhere
Self: Sized,
fn nack_after(
self,
delay: Duration,
) -> impl Future<Output = Result<(), AckError>> + Sendwhere
Self: Sized,
Negatively acknowledges the message, asking the broker to redeliver it no sooner than
delay from now.
The default returns AckError::Unsupported: a transport without native delayed
redelivery cannot honor the delay, and the default reports that honestly rather than
silently degrading to an immediate nack(true). The runtime never relies on this default
to honor a delay; it checks supports_nack_after first and
only calls nack_after when that is true, otherwise running its own deferred-republish
fallback. Brokers with native delayed redelivery override both methods.
§Errors
Returns AckError::Unsupported by default. Overrides return AckError under the same
conditions as nack.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".