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

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

Acknowledgement

What ack and nack do on each form: XACK on a stream, LREM on a reliable list, nothing on a simple list or a channel.

A handler ends a delivery with an outcome: ack, retry or drop. The runtime settles the delivery with that outcome, and each form turns it into its own Redis commands.

Formackretrydrop
StreamXACKXADD of a copy, then XACKXACK
Stream, claimingXACKthe entry stays pending and comes back after min_idleXACK
List, reliableLREM off the processing listLPUSH back onto the queue, then LREMLREM
List, simplenothingnothingnothing
Channel or patternnothingnothingnothing

On a stream a retry appends a copy and then acknowledges the original, so a crash between the two leaves a duplicate rather than a loss. The copy is a new entry with a new id. A claiming subscription retries through the pending entries list instead: nothing is appended, and the entry keeps its id and its delivery count. A simple list and Pub/Sub keep nothing to settle: the entry left Redis when it was popped, and a message is gone once it is pushed. An ack, a drop or a retry there reports AckError::Unsupported, and the runtime logs an ack / nack failed warning for each delivery. A retry there delivers nothing again, unless it is a retry_after or a cap is declared: both travel as a copy the runtime publishes.

Example​

A payment is charged, dropped when it is malformed, or retried when the gateway is busy.

/// One handler, three outcomes: the ack settles the entry, the drop settles it without a copy,
/// the retry appends a copy to `payments` and settles the original.
#[subscriber(RedisStream::new("payments").group("billing"))]
async fn charge(payment: &Payment, State(gateway): State<PaymentGateway>) -> HandlerOutcome {
if payment.amount_cents <= 0 {
tracing::warn!(payment.id, "malformed payment dropped");
return HandlerOutcome::drop();
}
match gateway.charge(payment).await {
Ok(()) => HandlerOutcome::ack(),
Err(err) => {
tracing::warn!(payment.id, %err, "charge failed, retrying");
HandlerOutcome::retry()
}
}
}