Consumers and prefetch
A queue pushes deliveries to its consumers, each within a window of unacknowledged deliveries that its acknowledgements reopen.
The diagram as text
- Queue orders messages wait in order → Consumer 1 prefetch 2: 2 unacknowledged: basic.deliver
- Queue orders messages wait in order → Consumer 2 prefetch 2: 2 unacknowledged: basic.deliver
- Consumer 1 prefetch 2: 2 unacknowledged → basic.ack frees a slot, and the next delivery is pushed
- Consumer 2 prefetch 2: 2 unacknowledged → Channel closed: its unacknowledged deliveries return, marked redelivered
- The queue spreads deliveries over its consumers in turn, skipping a consumer whose window is full
A consumer does not ask for messages. It registers with basic.consume, and the queue pushes
basic.deliver frames to it. Several consumers on one queue compete: the queue gives each message
to one of them, in turn.
The prefetch window is the number of deliveries a consumer may hold unacknowledged. Once the
window is full, the queue pushes nothing more to that consumer until an acknowledgement frees a
slot. This is how a slow handler slows the queue down instead of filling the service's memory.
RabbitMQ sets the window with basic.qos, per consumer, and reads 0 as no limit.
A delivery stays the consumer's until it is settled. basic.ack removes the message from the
queue. basic.reject with requeue puts it back, and without requeue the queue drops it or
dead-letters it. When a channel closes with deliveries still unsettled, the queue takes them back
and delivers them again with the redelivered flag set.
In this crate
Each subscription opens a channel of its own and one consumer on it. Before the consumer
starts, the subscription sends basic.qos with its window:
RabbitQueue::prefetch for one queue, or
LapinBroker::prefetch for every subscription
that sets none. The setting is a non-zero number, so a subscription that sets neither sends no
basic.qos and runs with no limit.
The window also bounds a batch. AMQP has no batch frame, so a batch handler's batch is collected
on the client from what the queue has already pushed: up to the size the mount site names, or
what arrived within batch_wait (50
milliseconds by default). A window smaller than the batch size caps the batch at the window.
A dropped subscription closes its channel, and RabbitMQ requeues what it held unsettled. How the runtime settles each delivery is on Settlement and retries.
The protocol rules are RabbitMQ's (consumer prefetch, consumer acknowledgements, work queues).