docs: ws-byte-adapter POC complete (GO) — resolve OQ-01, update framing facts
POC at /workspace/ws-byte-adapter-poc/ (not on main), all tests green: - call round-trip over axum WS ↔ adapter ↔ ChannelsAdapter ↔ channel-0 Dispatcher (published alkcall API only, no forks) - 3 MiB payload splits across 1 MiB WS messages, byte-intact reassembly - 20 interleaved calls reassemble without corruption/cross-correlation Findings merged: - OQ-01 resolved: byte-stream both directions, bounded mpsc (64 slots) inbound, outbound chunk-header parsing (frame-as-two-chunks live-confirmed), 1 MiB message cap with split, flush no-op, close → EOF → REQ-CH-02 - websocket.md: chunk ≠ frame on channel 0 (frame reassembly required); operationId is the request payload key - task ws-byte-adapter → completed with full Summary; ws-upgrade-session unblocks
This commit is contained in:
@@ -14,32 +14,28 @@ with their resolutions; new alkhttp OQs start at OQ-01.
|
||||
### OQ-01: WS ↔ byte-stream adaptation semantics
|
||||
|
||||
- **Origin**: [websocket.md](websocket.md), [ADR-067](decisions/067-websocket-carries-channels.md)
|
||||
- **Status**: open
|
||||
- **Status**: resolved (POC `ws-byte-adapter`; validated end-to-end — see
|
||||
the task's Summary in `tasks/websocket/byte-adapter.md`)
|
||||
- **Priority**: high
|
||||
- **Question**: The channels demux consumes bytes (`read_exact` on the
|
||||
8-byte header + payload); the mux writes chunks as contiguous byte
|
||||
sequences. A WebSocket is message-oriented. The adapter's contract
|
||||
needs nailing down before implementation:
|
||||
(a) inbound buffer bound (the alknet-tty precedent — bounded mpsc
|
||||
with `try_send` → `Full` → `Pending` backpressure, and the single-
|
||||
drainer ordered-write pattern from `pump_session` — is the working
|
||||
reference; bound value to lock during implementation);
|
||||
(b) write-side chunk boundary parsing (verified against alkcall
|
||||
source: the mux emits one mpsc payload per chunk, but a logical
|
||||
write above the mux — e.g. channel 0's `write_frame`, which issues
|
||||
prefix and body as separate `write_all`s — can surface as multiple
|
||||
chunks; the adapter must parse outgoing chunk headers rather than
|
||||
assume write-per-chunk; also confirm the WS-message cap policy for
|
||||
chunks up to `MAX_CHUNK_LEN` = 16 MiB — split across messages, and
|
||||
what the practical cap is for browser stacks);
|
||||
(c) flush mapping (`AsyncWrite::flush` → WS message emission point);
|
||||
(d) close mapping (WS close code → transport EOF → REQ-CH-02
|
||||
teardown; `AsyncWrite::shutdown` maps to the zero-length EOF
|
||||
sentinel (REQ-CH-01) then a WS Close frame — confirm this ordering
|
||||
against the mux's pump-exit behavior).
|
||||
- **Blocked on**: nothing (the spike resolved the factual
|
||||
sub-questions; the remaining items are implementation decisions to
|
||||
lock during the WS adapter task)
|
||||
- **Resolution**: The adapter treats the WS message stream as a byte
|
||||
stream in both directions; the 8-byte chunk header is the only
|
||||
framing. Inbound: WS read task → bounded mpsc (64 slots; backpressure
|
||||
= send awaiting capacity, applying TCP-level backpressure to the
|
||||
socket) → `AsyncRead` drains; channel close = EOF. Outbound: a writer
|
||||
task parses 8-byte chunk headers out of the pending byte buffer (live-
|
||||
confirmed: a single response frame arrives as TWO chunks —
|
||||
`write_frame`'s prefix and body surface as separate mux payloads) and
|
||||
emits one WS message per chunk, splitting at a 1 MiB
|
||||
`WS_MESSAGE_CAP` (receiver's boundary is the chunk header, not the
|
||||
message). Flush is a no-op (writes queue; the writer task emits
|
||||
independently). Close: WS close → read EOF → REQ-CH-02 teardown;
|
||||
`shutdown` closes the write channel (mux pumps emit zero-length
|
||||
sentinels on sender drop). Client-side consequence: chunk ≠ frame —
|
||||
channel-0 consumers reassemble length-prefixed frames from the byte
|
||||
stream; and the dispatcher reads `operationId` from the request
|
||||
payload.
|
||||
- **Cross-references**: ADR-067, [websocket.md](websocket.md),
|
||||
tasks/websocket/byte-adapter.md
|
||||
|
||||
### OQ-02: `/publish` body framing details
|
||||
|
||||
|
||||
Reference in New Issue
Block a user