Connection
Generated page
Model gemma-mtp, commit ef58254ca7be, 2026-08-16, sources: 6. Edit the code or the hand-written documentation instead.
What this module is responsible for
The Connection class provides a low-level, non-thread-safe transport for the Booblik protocol, managing the lifecycle of a single TCP connection and the framing of request/response pairs (Connection.cs:40-41).
Diagram
Connection Lifecycle and Thread Safety
The Connection class is explicitly marked as not safe for concurrent use (Connection.cs:36-38). Because requests and responses are matched by a correlationId in the order they are sent (Connection.cs:36-37), multiple callers sharing a single Connection would cause interleaved data, where one caller reads the response intended for another (Connection.cs:37). To avoid this, the architecture requires one Connection per caller or the use of a Producer which manages its own instance (Connection.cs:38).
Request-Response Correlation and Framing
The communication relies on a strict framing mechanism where SendAsync increments a _correlation counter and writes a frame containing the apiKey, apiVersion, and correlationId (Connection.cs:90-97). The ReceiveAsync method then reads the response frame and performs a critical check: if the received correlation does not match the expect value, a ProtocolException is thrown (Connection.cs:124-126). This ensures that the client does not misinterpret a response as belonging to a different request, which would otherwise lead to incorrect offsets being handed to the wrong caller (Connection.cs:122-123).
Protocol Error Handling and Validation
The client performs several layers of validation during the response phase:
- Frame Integrity: If the response length is outside the allowed range (
ResponseHeaderBytestoMaxFrameBytes), aProtocolExceptionis raised (Connection.cs:110-112). - Correlation Matching: As noted above, mismatched IDs trigger a
ProtocolException(Connection.cs:126). - Broker Errors: If the response contains a non-zero error code, a
BrokerExceptionis thrown (Connection.cs:131).
Metadata Decoding and Partition Information
The MetadataAsync method triggers a request to find topics and their partition states (Connection.cs:145). The response is processed by DecodeMetadata, which iterates through the byte stream to extract:
| Field | Type | Description |
|---|---|---|
topicCount | Int32 | Number of topics in the response (Connection.cs:310) |
nameLength | UInt16 | Length of the topic name (Connection.cs:315) |
partitionCount | Int32 | Number of partitions for the current topic (Connection.cs:320) |
PartitionInfo | Struct | Contains Partition (int), LogStartOffset (long), and HighWatermark (long) (Connection.cs:327-329) |
Produce and Fetch Request Mechanics
The client supports different interaction patterns for data movement:
ProduceAsync Payload Structure:
| Field | Type | Description |
|---|---|---|
topicNameLength | UInt16 | Length of the topic name (Connection.cs:194) |
partition | Int32 | Target partition ID (Connection.cs:199) |
ack | Byte | AckPolicy (None, Written, or Forced) (Connection.cs:201) |
recordCount | Int32 | Number of records in the batch (Connection.cs:202) |
FetchAsync (v2) Parameters:
| Parameter | Type | Description |
|---|---|---|
maxBytes | Int32 | Bounds the response in bytes (Connection.cs:263) |
maxWaitMillis | Int32 | How long the broker may hold a request (Connection.cs:264) |
minBytes | Int32 | Minimum bytes required before responding (Connection.cs:265) |
Key files
| File | Lines | What is there |
|---|---|---|
…/Booblik/Connection.cs | 88-102 | SendAsync implementation for framing and writing to the stream |
…/Booblik/Connection.cs | 104-135 | ReceiveAsync implementation for reading and validating response frames |
…/Booblik/Connection.cs | 303-344 | DecodeMetadata logic for parsing the metadata byte stream |
Behaviour that surprise
- The
Connectionclass is not thread-safe; sharing it between callers will cause them to read each other's answers due to thecorrelationIdmatching logic (Connection.cs:36-38). - A
ProduceAsynccall withAckPolicy.Nonewill returnnullimmediately without waiting for a response from the broker (Connection.cs:214-216). MetadataAsyncwill fail the entire request with an error if a single requested topic does not exist, rather than simply omitting it from the results (Connection.cs:141-143).