joule-moq-relay: an object is held once, and the socket keeps what arrives #583
Loading…
Reference in a new issue
No description provided.
Delete branch "relay/fanout-load"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Under load the relay collapsed with cores to spare. A new load test,
examples/fanout_load.rs, found two reasons, and this fixes the cheap part of both.One socket with a small buffer. The relay's UDP socket kept the kernel's default, about 212 KB. Each fan-out's acknowledgements arrive together, so at 2,000 viewers the kernel dropped about a million packets in 20 seconds. A dropped acknowledgement reads as loss, which means a retransmission and a smaller congestion window.
limits.quic_socket_buffer_bytesnow asks for 4 MiB, on the sockets the relay listens on and dials from.A payload copied per viewer, under the relay's one lock. Each subscriber got its own copy during the fan-out and more on the way to the wire. An object is now held once, from when it's read until the last QUIC stream has it acknowledged: the cache, every session's queue and every QUIC send buffer share one allocation.
Measured
Unmodified main against this branch, the same harness, 8 KB objects at 30/s (about 2 Mbit/s a viewer), relay pinned to 8 cores, two rounds:
Latency improved in most runs, but the host was busy (load average 20–32 of 32 threads), so I'm not quoting it as a result. The clearest pair is p99 at 2,000 viewers, 88 → 26 ms in the first round. In the second round, a noisier one, it was 974 → 815 ms.
An earlier run on a quieter host used the same buffer and a shared payload, without the QUIC zero-copy added here. It took the longest stall from one 256 KB keyframe at 2,000 viewers from 52–58 ms to 7–8 ms.
What this doesn't fix
SendStreamthat keeps no buffers gets an object's head and payload as one write, so the bridges see what they saw before.net.core.rmem_max, often 212992, so the relay logs a warning, and a deployment has to raise that limit to benefit.What ran
cargo test -p joule-moq-relay: 126 passed, covering all transports.-p joule-moq --lib: 128 passed.cargo check --workspace --all-targetsfor joule-code-rs. New tests:🤖 Generated with Claude Code