Перейти к основному содержимому
Эта страница ещё не переведена

Ниже показан английский оригинал.

message_id

message_id tags a publish with Nats-Msg-Id, so a repeat inside the stream's deduplication window is stored once.

The stream remembers the ids it stored for its deduplication window, two minutes unless the stream is configured otherwise. A second message with the same id inside the window is acknowledged and not stored, and its acknowledgement reports duplicate. An id derived from the input, such as order-{id}, makes a redelivered input publish the same message again without storing it twice. The id describes one message, so the handler body states it as a step on the publish builder. The step comes from JetStreamPublishSteps in this crate's prelude, and the body bounds its slot Out<impl Publisher<Options = JetStreamOptions>, Slot>. That bound ties the body to JetStream, and its signature says so. The step writes into the call's JetStreamOptions; the publish still leaves through the mount site's policy and codec. A test reads the value back with tb.out::<Slot>().with_options(&JetStreamOptions { .. }).

Example​

Every shipped order is archived under an id derived from the order, so a redelivered order is stored once.

/// The copy of an order kept in the archive stream.
#[derive(Debug, PartialEq, Deserialize, Serialize, Outgoing)]
#[outgoing(name = "archive.orders")]
struct Archived {
id: u64,
}

#[derive(OutSlot)]
#[publishes(Archived)]
struct Archive;

/// Archives every shipped order under a deduplication id, so a redelivered order is stored once.
/// The id belongs to the message, so the body states it, and its slot bound names the `JetStream`
/// options type.
#[subscriber(JetStreamSubject::new("orders.shipped", "ORDERS").durable("archiver"))]
async fn archive(
order: &Order,
Out(copies): Out<impl Publisher<Options = JetStreamOptions>, Archive>,
) -> HandlerOutcome {
let sent = copies
.message(&Archived { id: order.id })
.message_id(format!("order-{}", order.id))
.publish()
.await;
if let Err(err) = sent {
tracing::warn!(order.id, %err, "archive copy refused, redelivering");
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}