nx_sig2_txq.nx
buildroot/runtime/nx_sig2_txq.nx
about
nx_sig2_txq.nx -- FRAME-ATOMIC non-blocking WebSocket send queue for the signaling relay.
(four-pillar ADDRESS at the transport layer; root cause: the relay's blocking fan-out writes.)
THE TWO DEFECTS THIS CLOSES (source-confirmed 2026-07-09, [[project-nishi-videoops-four-pillars]]):
1. BLOCKING WRITES in a single-threaded fan-out: one slow receiver's full socket buffer STALLED
every room on the relay (head-of-line). Writes here use sendto(MSG_DONTWAIT) -- the relay
NEVER sleeps on a receiver. (Write-side only: the read path keeps its blocking semantics.)
2. PARTIAL-FRAME POISON: _wss_write_n bailed mid-frame on w<=0, leaving a torn WebSocket frame
on the stream -- every later byte misparsed (the field's silent video garbage). Here a frame
either goes out WHOLE (possibly across POLLOUT continuations from the queue) or is dropped
WHOLE before any byte touches the wire. Torn-frame-unavoidable (partial direct write + queue
full) is FATAL by design: the caller must treat the conn as poisoned and let the reap path
close it -- fail-stop beats fail-dirty.
Per-conn state (caller-allocated, indexed by conn slot ci):
txq slab: NX_S2TX_QBYTES per conn -- queued raw wire bytes (whole frames / frame remainders)
txh[ci]: queue head offset txl[ci]: queued byte count
Drop policy: a frame that cannot fit WHOLE in the queue is dropped whole and counted by the
caller (video P-gap -> the client's seq check + kreq recovers in ~1 RTT; JSON control re-sends).
license_tier: ORIGINAL
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_websocket_frame.nx
imported by: nx_sig2_bp_gate.nxnx_signaling_v2.nx
structs
| none |
consts
| 24 | const NX_S2TX_QBYTES: i64 = 262144 // 256KB/conn ~= 4 worst-case keyframes ~= 250ms drop horizon |
| 25 | const NX_S2TX_DONTWAIT: i64 = 0x40 // MSG_DONTWAIT: this write NEVER sleeps |
| 26 | const NX_S2TX_NOSIGNAL: i64 = 0x4000 // MSG_NOSIGNAL: a send to a dead peer returns -EPIPE, never SIGPIPE |
| 27 | const NX_S2TX_SENDFLAGS: i64 = 0x4040 // DONTWAIT | NOSIGNAL -- self-protecting regardless of signal disposition |
| 28 | const NX_S2TX_EAGAIN: i64 = 0 - 11 |
functions
| 30 | func s2tx_qptr(txq: *u8, ci: i64) -> *u8 |
| 37 | func s2tx_wr(fd: i64, p: *u8, n: i64) -> i64 |
| 45 | func s2tx_drain(txq: *u8, txh: *i64, txl: *i64, ci: i64, fd: i64) -> i64 |
| 67 | func s2tx_send(tx: *i64, ci: i64, fd: i64, finop: i64, payload: *u8, plen: i64) -> i64 |
| 121 | func main() -> i64 { return 0 } |