booblik

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 (ResponseHeaderBytes to MaxFrameBytes), a ProtocolException is 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 BrokerException is 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:

FieldTypeDescription
topicCountInt32Number of topics in the response (Connection.cs:310)
nameLengthUInt16Length of the topic name (Connection.cs:315)
partitionCountInt32Number of partitions for the current topic (Connection.cs:320)
PartitionInfoStructContains 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:

FieldTypeDescription
topicNameLengthUInt16Length of the topic name (Connection.cs:194)
partitionInt32Target partition ID (Connection.cs:199)
ackByteAckPolicy (None, Written, or Forced) (Connection.cs:201)
recordCountInt32Number of records in the batch (Connection.cs:202)

FetchAsync (v2) Parameters:

ParameterTypeDescription
maxBytesInt32Bounds the response in bytes (Connection.cs:263)
maxWaitMillisInt32How long the broker may hold a request (Connection.cs:264)
minBytesInt32Minimum bytes required before responding (Connection.cs:265)

Key files

FileLinesWhat is there
…/Booblik/Connection.cs88-102SendAsync implementation for framing and writing to the stream
…/Booblik/Connection.cs104-135ReceiveAsync implementation for reading and validating response frames
…/Booblik/Connection.cs303-344DecodeMetadata logic for parsing the metadata byte stream

Behaviour that surprise

  • The Connection class is not thread-safe; sharing it between callers will cause them to read each other's answers due to the correlationId matching logic (Connection.cs:36-38).
  • A ProduceAsync call with AckPolicy.None will return null immediately without waiting for a response from the broker (Connection.cs:214-216).
  • MetadataAsync will 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).

On this page