Skip to main content

Direct reply-to

Direct reply-to sends a reply straight to the requester's channel with no reply queue, at most once.

A request over direct reply-to: the request goes through an ordinary queue, the reply comes straight back to the requester's channelRequester channel consumesamq.rabbitmq.reply-to, no acksRequest published on that channelwith reply-to and a correlation-idRequest queuean ordinary queueResponder handlerDirectReplyTo on its replyReply on the default exchangerouting key = the reply-to it gotRequester channelreceives it, no queue betweenThe request resolvesmatched by its correlation-idReplies live in the requester's channel:a reply sent after that channel is gone is lost
The diagram as text
  1. Requester channel consumes amq.rabbitmq.reply-to, no acks → Request published on that channel with reply-to and a correlation-id
  2. Request published on that channel with reply-to and a correlation-id → Request queue an ordinary queue
  3. Request queue an ordinary queue → Responder handler DirectReplyTo on its reply
  4. Responder handler DirectReplyTo on its reply → Reply on the default exchange routing key = the reply-to it got
  5. Reply on the default exchange routing key = the reply-to it got → Requester channel receives it, no queue between
  6. Requester channel receives it, no queue between → The request resolves matched by its correlation-id
  7. Replies live in the requester's channel: a reply sent after that channel is gone is lost

The requester consumes the pseudo-queue amq.rabbitmq.reply-to in no-ack mode. It needs no declaration. A request published on the same channel with reply-to set to that name gets a private address: RabbitMQ rewrites the property to amq.rabbitmq.reply-to. followed by a suffix of its own.

The request travels like any message, through an exchange into a queue, to a consumer. The responder publishes its reply to the default exchange, with the reply-to it received as the routing key. RabbitMQ hands the reply directly to the requester's channel. No queue holds it.

A reply is delivered at most once. If the requester's channel is gone, the reply is dropped, and the requester has to send the request again.

In this crate​

LapinRequester opens a channel of its own on the first request, starts the reply consumer on it, and publishes every request on that channel. Each request carries a generated correlation-id, and the reply with the same id resolves the call. One task per requester reads the replies, on the runtime the broker connected on. A channel error closes the channel and loses the replies in flight; the next request opens a new one. The per-request timeout is what ends a request whose reply never comes.

Requests are transient by default: a request nobody waits for after its timeout gains nothing from surviving a restart. LapinRequest::persistent turns persistence on.

The responder is an ordinary handler with a reply. DirectReplyTo, mounted as a transform of its reply, sends each reply to the address the request named and echoes its correlation-id. A reply arrives on a consumer without acknowledgements, so settling it does nothing.

The protocol rules are RabbitMQ's (direct reply-to).