fix(rtc): pace WebRTC data-channel sends against SCTP buffered_amount (VA-105) #109
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/VA-105-rtc-datachannel-backpressure"
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?
Problem
The Desktop tab renders for a same-LAN viewer but shows a black screen for remote viewers, even though DRM/KMS capture works everywhere (all hosts ship real tiles). Observed 2026-07-04 on the identical build
0.3.0-12-g92b1f07: desktop-02 (same LAN as the browser, connected via peer-reflexive172.16.100.120) rendered; desktop-01 (X11 greeter, remote/STUN srflx) and desktop-03 (Wayland, remote) went black.Root cause: when the WebRTC data channel opens, the switchover re-baseline (
state.invalidate()) forces a full keyframe (~2040 tile messages, ~2.4 MB) andRtcUpgrade::sendpushed every message straight into SCTP with no regard for the channel'sbuffered_amount. A same-LAN peer drains the send buffer fast enough to survive the burst; a remote / high-RTT peer does not, so the webrtc-rs SCTP association overruns and breaks (webrtc_sctp::association: failed to handle_inbound: ErrChunk->DataChannel is not opened-> revert to WS) before the keyframe lands. The local-vs-remote split is the tell: SCTP drain rate, not capture, decides the outcome.Fix
Gate
RtcUpgrade::sendonRTCDataChannel::buffered_amount(). At/above a 256 KiB high watermark it waits (5 ms poll, bounded by a 3 s drain timeout) for the buffer to drain below the watermark before pushing the next message, pacing the keyframe burst to the link's real drain rate so every tile still lands on the data channel, just spread over time. If the buffer stays saturated past the timeout,sendreturns the newRtcError::Backpressure, whichDesktopRtc::try_sendroutes over the WS for that one frame without counting it towardMAX_CONSECUTIVE_SEND_FAILSteardown (the channel is healthy, just slow behind a slow link).Testing
just pre-commit(fmt + clippy--deny warnings+ build +test --lib) green in Docker.Fixes VA-105.