Skip to main content

Settlement

What ack, retry, retry_after and drop become on Pub/Sub, which acknowledges, rejects or keeps leasing each message.

Each handler outcome and the call the crate makes for it on Pub/SubHandlerOn Pub/Suback()Acknowledged:removed from the subscriptionretry()Nacked: delivered againafter the retry policy'swait, or dead-letteredretry_after(d)Held for d while theclient extends the lease,then nacked; refused ifd exceeds max_leasedrop()Acknowledged:never delivered againdrop() on thelast attemptNacked, so the servicemoves it to thedead-letter topicOn an exactly-once subscription the ack and the nackwait for the service to confirm them
The diagram as text
  1. Handler: ack(); retry(); retry_after(d); drop(); drop() on the last attempt
  2. On Pub/Sub: Acknowledged: removed from the subscription; Nacked: delivered again after the retry policy's wait, or dead-lettered; Held for d while the client extends the lease, then nacked; refused if d exceeds max_lease; Acknowledged: never delivered again; Nacked, so the service moves it to the dead-letter topic
  3. ack() → Acknowledged: removed from the subscription
  4. retry() → Nacked: delivered again after the retry policy's wait, or dead-lettered
  5. retry_after(d) → Held for d while the client extends the lease, then nacked; refused if d exceeds max_lease
  6. drop() → Acknowledged: never delivered again
  7. drop() on the last attempt → Nacked, so the service moves it to the dead-letter topic
  8. On an exactly-once subscription the ack and the nack wait for the service to confirm them

Pub/Sub has no verb for "discard without redelivery" other than the ack, so drop() acknowledges. The exception is the last delivery the subscription's dead-letter policy allows. There a nack is what moves the message to the dead-letter topic, so drop() nacks. The crate reads the attempt from the delivery. The cap comes from the registration's max_attempts(n), or from the subscription itself, read once at startup, when an operator set the policy outside the code. That read needs the pubsub.subscriptions.get permission; without it the service logs a warning and drop() acknowledges. The attempt count is approximate, so a count that reset makes drop() acknowledge too.

A decode failure drops the message by default (FailurePolicy), so on Pub/Sub it is acknowledged.

The subscription counts attempts and moves spent messages itself. retry() under a declared max_attempts is a nack like any other, and the service applies the cap. The runtime publishes no retry copy on this broker.

retry_after(d) keeps the delivery in the process. A task on the runtime the broker connected on waits for d and then nacks. Meanwhile the client goes on extending the lease, and the message counts against max_outstanding. A d longer than max_lease is refused at the call with PubSubError::DelayBeyondLease, because the lease would end first. If the process dies during the wait, the lease ends and the service delivers the message again: the delay is lost, the message is not.

On an exactly-once subscription the crate uses the client's confirmed ack and nack. An ack that returns has been accepted by the service, and a refused one is logged as a failed ack. On any other subscription an ack is best effort, and the message may still come back.