A consumer can receive a job, perform useful work and disappear before reporting completion. Deleting on delivery loses work if the consumer stops early. Keeping unacknowledged work forever stalls it after a failure. A delivery policy needs a way to return abandoned work to the ready state and a way to distinguish an old owner from a new one.
This build uses visibility leases. Reservation creates a delivery token and an expiry tick; the job leaves ready but remains active. Acknowledgement removes the live delivery. At the deadline, an unacknowledged delivery becomes ready again and its old token is invalid. Every reservation creates a new token, even when the job ID repeats. A token names one ownership interval; an ID names the underlying work.
Take job a, reserved at tick zero with visibility five. At tick four its token is live. At tick five it is expired. An acknowledgement at five must first advance the queue's clock, then discover that the old token no longer owns anything. A later reservation of a obtains token two. Otherwise an old worker could acknowledge the new worker's delivery accidentally.
deliveries = {1: {"id": "a", "deadline": 5}}
now = 5
expired = [token for token, job in deliveries.items() if job["deadline"] <= now]
ready = [deliveries.pop(token)["id"] for token in expired]
print(ready, 1 in deliveries)The model prepends expired jobs in reservation order. That choice is part of this exercise, not a universal broker ordering promise. Requeueing, priorities and multiple consumers can alter what a real application observes. A global prefetch bound limits simultaneous active deliveries here; RabbitMQ applies prefetch according to its own channel and consumer rules.
All times are arguments. Reject a backward or noninteger clock before modifying ownership. Equal ticks are legal because several operations can occur at the same logical time. A call that advances time can reclaim multiple deliveries, even when the requested token was never valid. Build tests should inspect the queue after these calls rather than assuming a false acknowledgement is globally side-effect-free.
Acknowledging after the effect allows redelivery when acknowledgement is lost. That favors retaining work but permits duplicate processing. A lease does not prove that the previous consumer has stopped: a slow consumer can continue running after expiry. Local token validation protects this queue's operations; an external database or payment provider needs its own transaction, idempotency or fencing mechanism.
RabbitMQ's ordinary manual-ack recovery is tied to channel/connection lifecycle, with delivery acknowledgement timeouts also available. Our exact-tick visibility model makes failure cases easy to test without pretending to reproduce that broker protocol. The checks, bug hunts and build establish deterministic redelivery and stale-token rejection in memory. They establish neither durable messages nor exactly-once delivery. Retry policy and effect deduplication address different parts of the problem next.