joule-moq-relay: an object is held once, and the socket keeps what arrives #583
Merged
dcharlot
merged 2 commits from 2026-11-02 18:36:39 -05:00
relay/fanout-load into main 2026-11-02
joule-moq-relay: an object is held once, and the socket keeps what arrives
All checks were successful
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (pull_request) Successful in 29s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (pull_request) Successful in 6s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 6s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 6s
wai-app and Create / wai-app · does this change touch it (pull_request) Successful in 6s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 50s
joule-code conformance gate / Build + round-trip C1-C4 vectors (pull_request) Successful in 3m6s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Successful in 8m44s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (pull_request) Successful in 42s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 13m10s
joule-code conformance gate / joule-moq-relay, every target (pull_request) Successful in 3m5s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 6s
wai-fleet service / does this change touch it (pull_request) Successful in 7s
WAI Studio / does this change touch it (pull_request) Successful in 6s
wai-fleet service / service · macos (pull_request) Successful in 44s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m1s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 1m24s
wai-fleet service / service · linux (pull_request) Successful in 2m0s
joule-code conformance gate / joule-moq-ingest, every target (pull_request) Successful in 5m39s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 6m18s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 10m6s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 10m18s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 11m42s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 12m28s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 1m50s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 4m29s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 6m42s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 9m44s
Under load the relay collapsed with cores to spare, for two reasons a load test showed. Its one UDP socket kept the kernel's default buffer, about 212 KB. Each fan-out's acknowledgements arrive together, so at 2,000 viewers of 2 Mbit/s the kernel dropped about a million packets in 20 seconds. A dropped acknowledgement reads as loss: a retransmission and a smaller congestion window. The buffer is now a setting, 4 MiB by default, for the sockets the relay listens on and dials from. The system caps it, so the relay warns when it gets less. Each subscriber also got its own copy of every payload, while the fan-out held the relay's one lock, and two more copies on the way to the wire. An object is now held once, from when it is read until the last QUIC stream has it acknowledged. The cache, every session's queue and every QUIC send buffer share one allocation, and a keyframe stops being N keyframes in memory. A transport that keeps no buffers still copies, once, where it writes, and a bridge to an earlier draft still gets an object's head and payload as one write. `examples/fanout_load.rs` is the load test. A bystander on its own track measures what the audience costs everyone else on the relay. Co-Authored-By: Claude Opus 5.5 <[email protected]>
joule-moq-relay: a fan-out load test: one publisher, N subscribers, a bystander, the relay's own memory and CPU
Co-Authored-By: Claude Opus 5.5 <[email protected]>