The `Conn` Lifecycle and Concurrency
Generated page
Model gemma-mtp, commit ef58254ca7be, 2026-08-16, sources: 6. Edit the code or the hand-written documentation instead.
Diagram
The Conn Thread-Safety Model
The low-level Conn implementation in Go is explicitly not safe for concurrent use; it requires one connection per goroutine because requests and responses are matched by a correlation ID in the order they were sent, and sharing a Conn would cause goroutines to read each other's answers (booblik.go:75-77). In the Kotlin implementation, while the BooblikConnection is designed for concurrent access, it maintains this strict ordering by using a single writer coroutine to prevent interleaved writes (BooblikConnection.kt:40-46).
The BooblikConnection Pipelining Mechanism
To allow multiple callers to use a single connection without interleaving bytes, BooblikConnection uses a Channel to queue Outgoing messages (BooblikConnection.kt:59). A single writer coroutine drains this channel, ensuring that the order in which requests are enqueued is the exact order in which they are written to the SocketChannel (BooblikConnection.kt:74-83).
Correlation ID Matching and Pending Requests
Asynchronous responses are matched back to their original callers using a ConcurrentLinkedQueue of Pending objects (BooblikConnection.kt:60). The Pending sealed class hierarchy manages different response types:
| Class | Purpose |
|---|---|
Produce | Completes a CompletableDeferred<ProduceResult> |
Metadata | Completes a CompletableDeferred<MetadataResult> |
Fetch | Completes a CompletableDeferred<FetchResult> |
The reader coroutine polls the head of this queue and uses checkOrder to verify that the correlationId in the response matches the expected ID (BooblikConnection.kt:192-195).
Failure Propagation and ConnectionClosedException
When a connection failure occurs, the fail method is called to ensure no caller is left waiting forever (BooblikConnection.kt:162-168). This method iterates through all remaining Pending requests in the queue and calls fail(ConnectionClosedException(cause)) on each one (BooblikConnection.kt:166-167).
Error Handling and Protocol Integrity
The client enforces protocol integrity by validating that the broker's response matches the request's correlationId (BooblikConnection.kt:194). If a response carries a different ID, it is treated as a critical error because it implies the broker is reordering responses, which would lead to delivering the wrong data to the wrong caller (ErrorCodeTest.kt:19-21). Additionally, the client must handle ErrorCode responses, such as UNSUPPORTED_VERSION, which are returned as part of the response frame (ErrorCodeTest.kt:39-40).
Key files
| File | Lines | What is there |
|---|---|---|
…/go/booblik.go | 78-81 | Definition of the non-thread-safe Conn struct |
…/client/BooblikConnection.kt | 50-61 | The BooblikConnection class and its internal queueing mechanism |
…/client/BooblikConnection.kt | 184-241 | The Pending sealed class hierarchy for request matching |
Behaviour that surprises
- Strict Ordering Requirement: A
BooblikConnectionis a pipelined connection where the broker is expected to answer in strict FIFO order; if the broker reorders responses, the client will throw an error rather than silently delivering the wrong data (BooblikConnection.kt:34-38). - Health Check Semantics: A health check using
Metadatais preferred over a simple TCP connect because a TCP handshake can succeed even if the broker process is hung and unable to process requests (Health.kt:14-18). - Correlation ID Persistence: Even when the broker returns an error like
UNSUPPORTED_VERSION, it is required to echo thecorrelationIdso the client can identify which request failed (ErrorCodeTest.kt:39-40).