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

下面显示的是英文原文。

retry_after

retry_after(delay) sets the message's visibility to the delay, so it returns on the same queue with its receive count, within 12 hours of its receive.

SQS holds a message back natively: ChangeMessageVisibility hides it for the delay, and the next receive after that hands it out again. Nothing is republished and no copy is made, so the message keeps its id, its attributes and its receive count. SQS counts whole seconds, so a fraction of a second rounds up. SQS keeps a message hidden for at most twelve hours from its receive, so the longest delay is what remains of those twelve hours. A longer delay is shortened to end with them, and the crate logs a warning that names the queue. The delay waits on the queue, not in the service, so a service that stops in the meantime loses nothing. SQS moves the message itself, so the registration names no retry publisher, and .out_retry(..) does not compile on an SqsQueue. A redrive policy counts a deferred receive like any other. In a test, tb.advance(delay) lets the delay pass on a paused clock.

Example​

An invoice whose payment has not cleared comes back five seconds later and is settled then.

/// How long an invoice whose payment has not cleared waits before it is checked again.
const RECHECK: Duration = Duration::from_secs(5);

/// The payment of an invoice clears within seconds, so the first receive asks for the invoice
/// again later and the second one settles it.
#[subscriber(SqsQueue)]
async fn settle(invoice: &Invoice, cx: &mut Context<'_>) -> HandlerOutcome {
if cx.headers().get_str(RECEIVE_COUNT_HEADER) == Some("1") {
tracing::info!(invoice.id, "payment not cleared yet");
// ChangeMessageVisibility to five seconds: nothing is republished.
return HandlerOutcome::retry_after(RECHECK);
}
tracing::info!(invoice.id, "invoice settled");
HandlerOutcome::ack()
}