Broker internals
How TCP connections, protocol parsing, commands, routing, consumers, and persistence fit together.
The broker implementation lives in apps/broker/src. Its main runtime is assembled by TcpServer, ClientConnection, CommandHandler, and ConsumerManager.
Inside the broker
The TCP command path converges on repositories and PostgreSQL.
Conceptual map of the current implementation. Use the linked source files in each guide for exact validation rules and runtime behavior.
1. TCP listener and connection lifecycle
TcpServer creates a Node.js TCP server. For each accepted socket it creates a ClientConnection, registers it with ConnectionManager, and supplies callbacks for validated protocol messages and socket closure.
A ClientConnection:
- Assigns an internal connection identifier.
- Holds a
FrameDecoderfor the socket's incoming byte stream. - Parses each complete frame through
ProtocolParser. - Sends outgoing messages using
FrameEncoder. - Tracks the registered client name and authenticated username.
- Resets its decoder and invokes the close callback when the socket closes.
The connection manager tracks active connection objects. A disconnect also triggers consumer cleanup and in-flight message recovery.
2. Protocol and validation
The protocol layer converts TCP chunks into complete frames, decodes the UTF-8 JSON payload, parses the message envelope, and validates its schema before dispatch.
See Protocol and framing for the wire format and message shapes.
3. Command dispatch
CommandHandler maps command names to dedicated handler functions. The current dispatch table includes:
CONNECTandAUTHQUEUE_DECLAREandQUEUE_DELETEEXCHANGE_DECLAREandEXCHANGE_DELETEBINDandUNBINDPUBLISHandCONSUMEACK,NACK, andCANCEL
The command handler allows only CONNECT and AUTH before a connection is authenticated. Other commands return an authentication-required response.
4. Routing and storage
The publish path looks up the exchange, reads its bindings, evaluates routing rules, and inserts one message row for each unique destination queue. The database work is performed inside a transaction.
The message repository also owns message claiming, acknowledgement, release, retry-limit evaluation, dead-letter routing, timeout recovery, and disconnect recovery.
5. Consumer dispatch
ConsumerManager maintains in-memory subscriptions and dispatch state. It chooses an eligible subscriber using round-robin ordering for a queue.
The current broker implementation enforces one unacknowledged message per connection-and-queue pair (prefetch = 1). The database claim uses FOR UPDATE SKIP LOCKED to claim a ready row without allowing concurrent workers to claim the same row.
6. Management HTTP server
The broker starts its HTTP server alongside the TCP listener. The dashboard communicates with this HTTP surface; application message producers and consumers use the TCP protocol.