Skip to main content

Path

The way of one NATS message through a RustStream service: the subscription, the delivery, the handler, the reply and the settlement, on Core and on JetStream.

The path of one message that is answered, on Core NATS on the left and on JetStream on the right, through one shared runtime pathCore subscriptionthe server pushesPull consumerbatches of 200NatsMessage::Coreheaders converted onceNatsMessage::JetStreammetadata read on demandDispatchone loop, or a lane per keyDecoderead in place from the payloadHandlerasync fn under #[subscriber]Replyencoded into a bufferNatsPublisherhands the buffer to the clientNothing to settleAckError::Unsupported+ACKsent without waiting
The diagram as text
  1. Core subscription the server pushes → NatsMessage::Core headers converted once
  2. Pull consumer batches of 200 → NatsMessage::JetStream metadata read on demand
  3. NatsMessage::Core headers converted once → Dispatch one loop, or a lane per key
  4. NatsMessage::JetStream metadata read on demand → Dispatch one loop, or a lane per key
  5. Dispatch one loop, or a lane per key → Decode read in place from the payload
  6. Decode read in place from the payload → Handler async fn under #[subscriber]
  7. Handler async fn under #[subscriber] → Reply encoded into a buffer
  8. Reply encoded into a buffer → NatsPublisher hands the buffer to the client
  9. NatsPublisher hands the buffer to the client → Nothing to settle AckError::Unsupported
  10. NatsPublisher hands the buffer to the client → +ACK sent without waiting

A Core message is pushed by the server into the subscription. A JetStream message arrives in answer to a pull request, which async-nats sends for 200 messages at a time. Either way the NatsMessage keeps the client's message as it came, payload included.

The headers are converted to the framework's map once, when the delivery is made. A message without headers builds no map at all. On Core, a request's reply subject is added as the reply-to header. On JetStream, the metadata is read from the acknowledgement subject when a handler asks for it, and not before.

The handler's reply is encoded into a buffer, and the publisher hands that buffer over to async-nats as it is, without a copy. A Core publish returns once the client has taken the message. A JetStream publish returns once the stream has acknowledged it.

The delivery settles after the reply. A JetStream acknowledgement is one message to the acknowledgement subject, sent without waiting for an answer. A Core delivery has nothing to settle: the call reports AckError::Unsupported and the runtime logs it. What each outcome does is on Settlement.

The benchmarks count this path: the instructions and allocations of one JetStream delivery, the client's work on the service's thread included.