pub enum Settle {
AtLeastOnce,
AtMostOnce,
}Expand description
Delivery guarantee of a subscription, set with AmqpAddress::settle.
Under AtLeastOnce the handler’s outcome is the delivery’s disposition,
and the runtime caps the attempts: AMQP 1.0 declares no node with a delivery limit and a
dead-letter address, so max_attempts and dead_letter read the same here as on every broker.
§Examples
Five deliveries per order, then the orders.dead address. An order that is not ready yet
comes back in half a minute, through a retry publisher that stamps each copy:
use std::time::Duration;
use ruststream::runtime::{Outgoing, PublishContext};
use ruststream_amqp::prelude::*;
use serde::Deserialize;
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[subscriber(AmqpAddress::queue("orders").settle(Settle::AtLeastOnce))]
async fn fulfil(order: &Order) -> HandlerOutcome {
if order.id == 0 {
// Not ready yet: ask for the delivery again in half a minute.
return HandlerOutcome::retry_after(Duration::from_secs(30));
}
tracing::info!(order.id, "fulfilled");
HandlerOutcome::ack()
}
/// Stamps a deferred copy with the address it came from, so a redelivery is recognisable.
struct Retried;
impl<C, Options> PublishTransform<ForReply<C>, Options> for Retried {
type Destination = Reads;
fn apply(
&self,
out: &mut Outgoing<'_>,
_options: &mut Option<Options>,
cx: &PublishContext<'_, C>,
) {
out.headers_mut()
.insert("x-retried-from", cx.name().to_owned());
}
}
#[ruststream::app]
fn app() -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(
AmqpBroker::new("amqp://artemis:artemis@localhost:5672"),
|b| {
b.include(fulfil)
.max_attempts(nonzero!(5u32))
.dead_letter("orders.dead")
.out_retry(Publish)
.transform(Retried);
},
)
}Variants§
AtLeastOnce
Deliveries are settled by the handler. The default.
ack sends accepted. A retry, nack(true), sends modified with delivery-failed,
never released, so the broker counts the attempt in delivery-count. A drop,
nack(false), sends rejected, and the broker’s dead-letter policy decides what follows.
AtMostOnce
Deliveries are settled on receipt, so a message is gone whether the handler finished or
not; ack and nack report
AckError::Unsupported.
Trait Implementations§
impl Copy for Settle
impl Eq for Settle
impl StructuralPartialEq for Settle
Auto Trait Implementations§
impl Freeze for Settle
impl RefUnwindSafe for Settle
impl Send for Settle
impl Sync for Settle
impl Unpin for Settle
impl UnsafeUnpin for Settle
impl UnwindSafe for Settle
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more