fix(router): timer-driven reorder flush so a stalled leg degrades gracefully - #4233
Merged
Merged
Conversation
…cefully The per-frame reorder skip-flush only ran INSIDE reorder.Insert — it fired on the next out-of-order packet to arrive. A leg that goes fully silent (dead/black-holing) delivers nothing to trigger it, so the frontier gap ages unbounded and the stream wedges to zero (observed live: reorder gap_age ~10s while the download stalled and the connection dropped mid-transfer). Add a periodic release: reorderBuffer.FlushIfStalled() runs the same skip gate (skipCapable && gap held past reorderTimeout) without needing a triggering insert; routeMux.flushStalledReorder() wraps it + advances the SACK tracker like deliverData; RouteGroup.reorderFlushServiceFn pushes released payloads to readCh on the same watched-close path as handleDataPacket, driven by a 500ms service loop (shorter than the 1.5s reorderTimeout). A no-op for non-per-frame groups (gated on skipCapable), so it is safe to start unconditionally. Net: a silent/dead leg's gap is released within ~one reorderTimeout of going quiet, the buffer delivers past it, and SACK/TCP recovers the skipped seqs — the proxy degrades to the surviving legs' rate instead of wedging. Graceful degradation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The per-frame reorder skip-flush only ran inside
reorder.Insert, firing on the next out-of-order packet to arrive. A leg that goes fully silent delivers nothing to trigger it, so the frontier gap ages unbounded and the stream wedges to zero — observed live as a reordergap_ageof ~10s while a download stalled and the connection dropped mid-transfer.Adds a periodic release:
FlushIfStalled()runs the same skip gate (skip-capable + gap held pastreorderTimeout) without a triggering insert; the mux wrapper advances the SACK tracker likedeliverData; a 500msreorder-flushservice loop pushes released payloads toreadChon the same watched-close path ashandleDataPacket. No-op for non-per-frame groups (gated onskipCapable).Net: a silent/dead legs gap is released within ~one
reorderTimeoutof going quiet, the buffer delivers past it, and SACK/TCP recovers the skipped sequences — the proxy degrades to the surviving legs rate instead of wedging. This is the graceful-degradation half of the mux-stability work. Developed with AI assistance (Claude).