Retry
The attempt cap and the dead-letter destination of a registration appear on its receive operation as the x-ruststream-retry extension.
max_attempts(n) is maxAttempts, and dead_letter(name) is deadLetter.
AsyncAPI has a field for neither: a binding models a dead-letter queue only for SQS and SNS, and nothing models an attempt cap.
So the document carries them as an extension of the operation.
The dead-letter destination is a channel of its own, with a send operation, since the registration publishes there.
Retry copies sent to a named destination add retryDestination, with its channel (see Retry slot).
Copies that return to the subscription's own address add nothing: that channel is already in the document.
A registration that declares none of this has no extension.
The example runs with cargo test --example asyncapi_reports --features macros,memory,asyncapi.
Example
- Macros
- Manual
fn app() -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
b.include(confirm);
b.include(accept).out(Tenants, Publish).build();
b.include(ship);
// The cap and the dead-letter destination reach the document with the registration.
b.include(charge)
.max_attempts(nonzero!(3u32))
.dead_letter("payments.dead");
})
}
fn app() -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(MemoryBroker::new(), |b| {
b.include(
subscriber("order-requests", Confirm)
.describe("Confirms every order request.")
.reply()
.to("confirmations")
.build(),
);
b.include(subscriber("orders", Accept).build())
.out(Tenants, Publish)
.build();
b.include(subscriber("shipments", Ship).build());
// The cap and the dead-letter destination reach the document with the registration.
b.include(subscriber("payments", Charge).build())
.max_attempts(nonzero!(3u32))
.dead_letter("payments.dead");
})
}