Skip to main content

Path

The way of one RabbitMQ delivery through a RustStream service: the push, the handler, the reply and the acknowledgement.

The path of one RabbitMQ delivery that is answered, from the queue to its acknowledgementQueuepushes within the prefetch windowbasic.deliveron the subscription's own channelLapinMessagebody kept, headers read on arrivalDispatchone loop, or a lane per keyDecodethe codec reads the bodyHandlerasync fn under #[subscriber]Replyencoded into the loop's bufferLapinPublisherbasic.publish of the replySettlementbasic.ack or basic.reject
The diagram as text
  1. Queue pushes within the prefetch window → basic.deliver on the subscription's own channel
  2. basic.deliver on the subscription's own channel → LapinMessage body kept, headers read on arrival
  3. LapinMessage body kept, headers read on arrival → Dispatch one loop, or a lane per key
  4. Dispatch one loop, or a lane per key → Decode the codec reads the body
  5. Decode the codec reads the body → Handler async fn under #[subscriber]
  6. Handler async fn under #[subscriber] → Reply encoded into the loop's buffer
  7. Reply encoded into the loop's buffer → LapinPublisher basic.publish of the reply
  8. LapinPublisher basic.publish of the reply → Settlement basic.ack or basic.reject

The queue pushes the delivery to the subscription's consumer while its prefetch window has room. lapin hands it over with the body in a buffer of its own. LapinMessage keeps that buffer as the body, without a copy. It reads the headers when the delivery arrives: the string and byte entries of the header table, plus the native properties a handler reads as headers (content-type, correlation-id, reply-to, message-id, the priority and the expiration). The exchange, the routing key, the redelivered flag and the delivery tag ride beside them as the delivery's context.

The runtime takes the delivery from the subscription's stream and runs it in its dispatch loop. The codec decodes the body, and the handler runs.

A reply is encoded into a buffer the dispatch loop reuses. The publisher lends those bytes to lapin, which copies them into the frame it sends. The four identity headers go out in their native properties, so a consumer that is not a RustStream service finds them where AMQP puts them. Every other header goes into the header table as a byte string. The routing key is the reply's destination, and the exchange is the publish policy's: the default exchange unless the policy names another.

The delivery settles after the reply, on the channel it arrived on. ack sends basic.ack. retry() and drop send basic.reject, with and without requeue. A reply that fails to publish settles the delivery as a retry. Settlement and retries draws what each outcome becomes.

What this path costs per message, against the raw lapin client, is on Benchmarks.