Path
The way of one message through a RustStream service, on a stream file and on a pipe: the reader, the channel, the handler, the reply and the write.
The diagram as text
- Stream file: Client consumer reads the file; Driver task stamps the generation; Channel of 64; FileSubscriber drops old generations; Batching under batch(n); FileContext, then decode; Handler #[subscriber] fn; FilePublisher envelope if headers; Append, flush into the file
- Pipe: stdin thread parses the line; Reader task of the subscription; Channel of 64; StdioSubscriber one message per poll; Batching under batch(n); Decode; Handler #[subscriber] fn; StdioPublisher envelope if needed; stdout thread writes the line
- Client consumer reads the file → Driver task stamps the generation
- Driver task stamps the generation → Channel of 64
- Channel of 64 → FileSubscriber drops old generations
- FileSubscriber drops old generations → Batching under batch(n)
- Batching under batch(n) → FileContext, then decode
- FileContext, then decode → Handler #[subscriber] fn
- Handler #[subscriber] fn → FilePublisher envelope if headers
- FilePublisher envelope if headers → Append, flush into the file
- stdin thread parses the line → Reader task of the subscription
- Reader task of the subscription → Channel of 64
- Channel of 64 → StdioSubscriber one message per poll
- StdioSubscriber one message per poll → Batching under batch(n)
- Batching under batch(n) → Decode
- Decode → Handler #[subscriber] fn
- Handler #[subscriber] fn → StdioPublisher envelope if needed
- StdioPublisher envelope if needed → stdout thread writes the line
The subscription's task reads ahead of the handler. It takes each message off the client, opens
the envelope and copies the payload into a buffer of its own. It adds the message's
number in the stream-sequence header, then queues the delivery on a channel of up to 64. The
handler reads from that channel, so the next message is out of the file while the current one is
handled.
On a file, every delivery carries the generation the reader was in when it read it. A seek opens a new generation, and the subscription drops what was queued under the old one. A delivery also holds a shared reference to the subscription's seeker, so building its context per message only counts references.
The handler's reply is encoded into a buffer the dispatch loop reuses. The publisher copies those bytes into the message it hands the client, and wraps them in the envelope only when the message has headers, or on a pipe when a line would change the payload. A file publish returns once the append is flushed to the file. A reply written to the file the subscription reads is passed over by its reader, because it sits under another stream key.
The delivery settles after the reply. On both transports an ack and a nack report that they are unsupported, as Settlement draws.