Skip to main content

Lifecycle

NatsBroker::new records configuration, connect dials, startup subscribes each subject or creates each consumer, and shutdown drains.

The broker's three states as types, and what each transition does on NATSBrokerOn NATSNatsBroker::new(addresses)ConnectedNatsBrokerClosedNatsBrokerthe drained countersAddresses andoptions, no I/ODial with theconnect optionsEach Core subscription:SUB, then a flushEach JetStream one:find the stream,create the consumerMark closed,then drainA publisher that outlives the connectionanswers NatsError::Closed, never a silent success
The diagram as text
  1. Broker: NatsBroker::new (addresses); ConnectedNatsBroker; ClosedNatsBroker the drained counters
  2. On NATS: Addresses and options, no I/O; Dial with the connect options; Each Core subscription: SUB, then a flush; Each JetStream one: find the stream, create the consumer; Mark closed, then drain
  3. NatsBroker::new (addresses) → ConnectedNatsBroker: connect(self)
  4. ConnectedNatsBroker → ClosedNatsBroker the drained counters: shutdown(self)
  5. Addresses and options, no I/O → Dial with the connect options
  6. Dial with the connect options → Each Core subscription: SUB, then a flush
  7. Each Core subscription: SUB, then a flush → Each JetStream one: find the stream, create the consumer
  8. Each JetStream one: find the stream, create the consumer → Mark closed, then drain
  9. A publisher that outlives the connection answers NatsError::Closed, never a silent success

new does no I/O, so the service's builder stays synchronous. It takes one address or a comma-separated list, and with_options attaches the async-nats connect options. The runtime connects the broker when the app starts. Connect dials with those options, and a server it cannot reach fails the start with NatsError::Connect.

Each subscription's descriptor resolves once, against the connected broker. A Core subscription sends SUB and then waits for a flush round trip. The server has registered the subscription by then, so a producer on another connection cannot publish into a gap. A JetStream subscription looks its stream up by name and creates its pull consumer, both requests the server answers. A stream that does not exist fails the start with NatsError::JetStream.

Shutdown marks the connection closed first, so a publisher that aliases it cannot slip a message in. Then it drains the client: the subscriptions stop, what was already published is flushed, and the connection closes. ClosedNatsBroker carries the client's counters: messages sent, messages received and connects.

A publisher paired before the shutdown is a handle the shutdown cannot take back. It answers NatsError::Closed with the subject it was asked to publish to.

The in-process transport follows the same ladder. It parses the addresses as connect does, and reads no_echo and the inbox prefix from the connect options.