跳到主要内容
本页尚未翻译

下面显示的是英文原文。

plugin_dme

Delay::plugin_dme hands a delayed copy to RabbitMQ's delayed-message-exchange plugin instead of a waiting queue.

The crate publishes the copy to an x-delayed-message exchange with the delay in its x-delay header, then acknowledges the original. The plugin holds each message for its own delay and then routes it to the origin queue. So a short delay never waits behind a long one, and one exchange serves every delay. The exchange is <queue>.delay; Delay::plugin_dme_named names another, which several queues may share. The released copy carries x-ruststream-retry-count raised by one, as with a waiting queue.

The backend sits behind the crate's plugin-dme feature, and the plugin has to be enabled on the server. With declare_topology(true) the service declares the exchange and binds the origin queue to it. On a broker that declares nothing, the operator provisions both, and the subscription checks at startup that the exchange exists.

Example​

Each reminder waits as long as it asks for. The in-process transport releases the copy like a waiting queue; the plugin's own release order shows only against a server with the plugin.

/// Each reminder waits as long as it asks, in the plugin's exchange `reminders.delay`. A short
/// wait is released on time even while a long one is still held.
#[subscriber(RabbitQueue::new("reminders").delay(Delay::plugin_dme()))]
async fn remind(reminder: &Reminder, ctx: &mut Context<'_>) -> HandlerOutcome {
if ctx.headers().get_str(RETRY_COUNT_HEADER).is_none() {
return HandlerOutcome::retry_after(Duration::from_secs(reminder.after_secs));
}
tracing::info!(reminder.id, "reminder sent");
HandlerOutcome::ack()
}

#[ruststream::app]
fn app() -> impl App {
// The service declares the delayed exchange; the plugin has to be enabled on the server.
let broker = LapinBroker::new("amqp://localhost:5672").declare_topology(true);
RustStream::new(AppInfo::new("reminders", "0.1.0")).with_broker(broker, |b| {
b.include(remind);
})
}