Skip to main content

Path

The way of one ZeroMQ message through a RustStream service: the socket task, the channel, the handler, the reply's frames and the send.

The path of one ZeroMQ message that is answered, from the peer's frames to the reply's framesPeersends three framesSocket taskowns the socket, reads one messageZmqMessagename, headers, and the payload frameChannelread_ahead deepDispatchone at a time, or a batchDecoderead in place from the payload frameHandlerasync fn under #[subscriber]Replyencoded into a buffer it hands overFramesthe buffer becomes the payload framePublishersends, retrying while the peer attachesSettlementack answers Unsupported
The diagram as text
  1. Peer sends three frames → Socket task owns the socket, reads one message
  2. Socket task owns the socket, reads one message → ZmqMessage name, headers, and the payload frame
  3. ZmqMessage name, headers, and the payload frame → Channel read_ahead deep
  4. Channel read_ahead deep → Dispatch one at a time, or a batch
  5. Dispatch one at a time, or a batch → Decode read in place from the payload frame
  6. Decode read in place from the payload frame → Handler async fn under #[subscriber]
  7. Handler async fn under #[subscriber] → Reply encoded into a buffer it hands over
  8. Reply encoded into a buffer it hands over → Frames the buffer becomes the payload frame
  9. Frames the buffer becomes the payload frame → Publisher sends, retrying while the peer attaches
  10. Publisher sends, retrying while the peer attaches → Settlement ack answers Unsupported

The task that owns a subscription's socket receives one message at a time. It splits the frames into a name, the headers and the payload. The payload is the received frame itself, not a copy, and the handler's input is decoded from it in place.

The message goes into the subscription's channel, read_ahead deep, and the dispatch loop takes it from there. A batch handler gets the messages already in the channel, up to the size the mount site names, or what arrived within 20 milliseconds of the first.

The handler's reply is encoded into a buffer the publisher takes over. The buffer becomes the payload frame, and the name and the headers go in frames of their own in front of it, so the payload is not copied. A publisher on the bind side attached its socket at startup; one that dials attaches it on its first publish. A queue send that finds no peer connected yet retries every 50 milliseconds, for up to five seconds, and then fails with an error naming the destination.

The delivery settles after the reply. ZeroMQ has nothing to settle, so the ack answers Unsupported at once, as Settlement draws. What a message costs on this path, in instructions and allocations, is on Benchmarks.