Skip to main content

Settlement

What ack, drop, retry and retry_after become on Pulsar: acknowledgements and redeliveries the broker counts toward the client's dead-letter policy.

Each outcome of a handler on Pulsar: what the crate asks the client for, and what the broker doesHandlerThe crate callsBrokerack()ack_with_idacknowledged,never sentagainretry()nack_with_idsent againat once,count + 1retry_after(d)waits d, thennack_with_idsent againafter d,count + 1drop()ack_with_idacknowledged:goneno outcomenothing; theclient's timeracts latersent again afterack_timeout,count + 1The count rises on Shared and KeyShared subscriptions only:the other types keep none
The diagram as text
  1. Handler: ack(); retry(); retry_after(d); drop(); no outcome
  2. The crate calls: ack_with_id; nack_with_id; waits d, then nack_with_id; ack_with_id; nothing; the client's timer acts later; The count rises on Shared and KeyShared subscriptions only: the other types keep none
  3. Broker: acknowledged, never sent again; sent again at once, count + 1; sent again after d, count + 1; acknowledged: gone; sent again after ack_timeout, count + 1
  4. ack() → ack_with_id
  5. ack_with_id → acknowledged, never sent again
  6. retry() → nack_with_id
  7. nack_with_id → sent again at once, count + 1
  8. retry_after(d) → waits d, then nack_with_id
  9. waits d, then nack_with_id → sent again after d, count + 1
  10. drop() → ack_with_id
  11. ack_with_id → acknowledged: gone
  12. no outcome → nothing; the client's timer acts later
  13. nothing; the client's timer acts later → sent again after ack_timeout, count + 1

Every outcome is a call on the subscription's client consumer, which its driver task makes. ack and drop acknowledge the message, because Pulsar has no command that rejects one for good: a message that should not come back is acknowledged, and one that keeps failing reaches the dead-letter topic by the cap. retry asks the broker to deliver it again at once.

retry_after(d) holds the delivery unacknowledged in the service for d, then sends the same negative acknowledgement. The wait runs on the runtime the broker connected on. A delay not shorter than the subscription's ack_timeout is refused, because the client's timer would bring the message back first.

A delivery no handler settles stays unacknowledged. With an ack_timeout, the client asks for it again once the timeout passes, as Acknowledgement draws. Without one, it comes back only when the consumer disconnects.

Retries​

A retry on Pulsar: a negative acknowledgement now or after a wait, the broker's redelivery, and the client's capA deliverythe broker counts its redeliveriesThe handler returnsretry(), or retry_after(d)retry():negative acknowledgementat onceretry_after(d): heldin the process for d,then the sameThe broker delivers it againcount + 1The client's dead-letter policy:has the count reached max_attempts?Below the cap:the handlergets it againAt the cap: producedto the dead-lettertopic, original ackedA cap on an Exclusive or a Failover subscriptionrefuses to start: neither counts redeliveriesA stop during the wait loses the wait, not the message:the message stays unacknowledged
The diagram as text
  1. A delivery the broker counts its redeliveries → The handler returns retry(), or retry_after(d): handled
  2. The handler returns retry(), or retry_after(d) → retry(): negative acknowledgement at once
  3. The handler returns retry(), or retry_after(d) → retry_after(d): held in the process for d, then the same
  4. retry(): negative acknowledgement at once → The broker delivers it again count + 1
  5. retry_after(d): held in the process for d, then the same → The broker delivers it again count + 1
  6. The broker delivers it again count + 1 → The client's dead-letter policy: has the count reached max_attempts?
  7. The client's dead-letter policy: has the count reached max_attempts? → Below the cap: the handler gets it again: below
  8. The client's dead-letter policy: has the count reached max_attempts? → At the cap: produced to the dead-letter topic, original acked: at the cap
  9. A cap on an Exclusive or a Failover subscription refuses to start: neither counts redeliveries
  10. A stop during the wait loses the wait, not the message: the message stays unacknowledged

Nothing is published to bring a message back: the broker delivers the same message again and counts it. A registration's max_attempts and dead-letter topic become the client's dead-letter policy. The client delivers a message while its count is below the cap, so the handler sees it max_attempts times. At the cap the client produces it to the dead-letter topic and acknowledges the original.

The two settings go together: a registration that declares one without the other refuses to start, and so does a cap on an Exclusive or a Failover subscription, whose messages always arrive with a count of zero.

The count is the client's own, and a delivery does not report it. A process that stops during a retry_after wait loses the wait and not the message: it is still unacknowledged, and the broker delivers it again after the acknowledgement timeout or once the consumer's connection is gone.