Transport
Generated page
Model gemma-mtp, commit f508a4b65b3f, 2026-08-15, sources: 6. Edit the code or the hand-written documentation instead.
Diagram
Transport modes
The server supports two distinct transport mechanisms, which are configured via ServerConfig in BooblikServer.kt:45-64.
| Mode | Mechanism | Implementation |
|---|---|---|
SELECTOR | Non-blocking NIO with a dedicated selector thread and coroutine suspension. | SelectorConnection |
VIRTUAL_THREADS | Blocking sockets where each session runs on a virtual thread. | BlockingConnection |
SelectorLoop mechanics
The SelectorLoop is the engine that turns NIO readiness into coroutine suspension. It operates on a dedicated thread to avoid deadlocks during SelectionKey.register calls on certain JDK implementations (SelectorLoop.kt:48-55).
To ensure thread safety, interest changes are not applied directly from other threads. Instead, they are posted to a ConcurrentLinkedQueue and applied by the loop thread itself (SelectorLoop.kt:94-96). Every change triggers a selector.wakeup() to ensure the loop processes the pending actions immediately (SelectorLoop.kt:95-96).
SelectorConnection and suspension
SelectorConnection implements the Connection interface by using the SelectorLoop to suspend coroutines when I/O is not ready. When readFully or writeFully encounters a zero-byte operation, it calls loop.awaitReadable(key) or loop.awaitWritable(key) (Connection.kt:65-75). This suspends the session coroutine, freeing up the thread until the SelectorLoop detects readiness and resumes the CancellableContinuation (SelectorLoop.kt:80-81).
BlockingConnection and virtual threads
BlockingConnection serves as the baseline for performance measurements (Connection.kt:100-102). While virtual threads make blocking code efficient, they do not virtualize disk I/O. Consequently, a transferTo call that triggers a page fault can pin the carrier thread to the disk, potentially stalling the executor (Connection.kt:104-106).
PartialFrame assembly
The protocol requires full frames to be assembled from the stream. The PartialFrameTest verifies that the selector correctly handles frames split across multiple packets (PartialFrameTest.kt:40-56) and even frames delivered one byte at a time (PartialFrameTest.kt:66-76). This ensures the SelectorConnection correctly waits for more data via loop.awaitReadable when a read returns zero (Connection.kt:66).
Connection failure and frame corruption
The server is designed to be resilient to malformed data. If a client sends an unserviceable request (e.g., an unsupported version), the broker responds with an ErrorCode but keeps the connection alive (PartialFrameTest.kt:80-109). However, an "absurd" frame length—such as a request claiming a massive size—is treated as a fatal error that drops the connection to protect the broker's memory (PartialFrameTest.kt:112-129).
Key files
| File | Lines | What is there |
|---|---|---|
…/net/BooblikServer.kt | 25-34 | Transport enum defining the two execution models. |
…/nio/Connection.kt | 55-142 | Connection interface and its two implementations. |
…/nio/SelectorLoop.kt | 31-41 | The dedicated thread and management of the Selector. |
…/net/PartialFrameTest.kt | 29-175 | Tests for split packets and frame assembly. |
Behaviour that surprises
- Interest changes are asynchronous: Because
SelectionKey.interestOpscan block or be ineffective during aselect()call,SelectorLoopmust queue changes and useselector.wakeup()to apply them safely (SelectorLoop.kt:26-28). - Disk I/O pins carrier threads: Even when using virtual threads,
BlockingConnectioncan cause a carrier thread to stall iftransferToencounters a page fault during disk I/O (Connection.kt:104-106). - Zero-copy requires the raw channel: Wrapping a
SocketChannelin a decorator can silently turn asendfilepath into a copy loop, makingtransferTargeta critical property for performance (Connection.kt:28-30).