Repository navigation
fix(net): follow-ups to #5133 (deferred FIN on drop, reprioritize open group streams) - #5164
Conversation
An idle closed watch owns the stream, so finish() only records the FIN. Dropping the stream before the next poll discarded the watch and let the backend reset instead. Reclaim the interrupted watch and apply a deferred finish as well as a deferred reset, like the in-flight write path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A subscription REQUEST_UPDATE changed the subscriber priority for groups opened afterwards, but each group stream captured its priority once, so a long or flow-control-blocked stream kept the old one after the update was acknowledged. TrackServe now owns the priority in a kio channel that every group stream follows while open, like lite's per-group track priority. Backport of #5162. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Automated review of 6f0a2bd Both fixes look right and each has a test that fails without it. Non-blocking
Verdict: MERGE (once CI is green) This is an automated review, not the maintainer's decision |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 6f0a2bd
No concrete new correctness bugs found in the full diff and relevant request-update, group lifecycle, kio, writer, and transport code. The direction is sound: preserve the deferred FIN with the existing interrupted-watch salvage path, and propagate subscription priority through the existing kio mechanism. Keeping these fixes local is preferable to rejecting benign updates or introducing another scheduler abstraction.
Non-blocking coverage: agree with the independent Grok review. Extend rs/moq-net/src/ietf/publisher.rs:4623–4643 with two successive priority updates while a stream awaits its FIN acknowledgement; extend rs/moq-tokio/src/transport.rs:1184–1201 with both deferred finish and reset, asserting that only the reset wins.
Verification: GitHub-only static review; I did not run tests or benchmarks. The four head workflows (Check, WASM, Platform, Android) were queued when checked; the local test results are author-reported.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f0a2bddad
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.session.clone(), | ||
| msg, | ||
| self.track.subscription().priority, | ||
| self.priority.consume(), |
There was a problem hiding this comment.
Add a benchmark for priority-update fanout
Each open group now owns a consumer of the shared priority channel, so one REQUEST_UPDATE wakes and polls every in-flight group across affected subscriptions. The added test covers only one stream, and the existing rs/moq-net benchmarks do not exercise this IETF update path. Add a benchmark sweeping subscription and open-group counts so superlinear fanout costs are visible.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
Mirrors the review follow-ups that landed with #5162 on main: a test for the Closed state, and comments on where a moved priority applies and why the ignored write cannot fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merge summary #5162 merged on main (799d8c0). 55089ca mirrors its review follow-ups onto
Decisions, matching #5162:
The rest is review-only on top of 6f0a2bd, which the OpenAI and Codex reviews cover. (Written by Claude Opus 5.5) |
|
Automated follow-up review of 55089ca (since 6f0a2bd) This push is just tests and comments, and it covers three of the earlier notes:
Still open, all non-blocking:
No new issues. Verdict: MERGE (once CI is green) This is an automated review, not the maintainer's decision |
Follow-up to #5133, fixing the two Codex P2 findings on that PR. Both bugs also exist on
main, which has its own PRs: #5156 and #5162.1. A deferred FIN is lost when a send stream drops mid-watch (moq-tokio)
#5133 pulled in #4658's moq-tokio change, which lets
poll_closedwatch an idle, unfinished send stream. That watch (SendState::Closing) owns the stream. Afinish()while it is held is only deferred, andDrop'sClosingbranch rescued a deferred reset but not a deferred FIN. Dropping the stream then gave the backend's default reset instead of the FIN thatfinish()had reported as successful. TheClosingdrop branch now applies a deferred finish too, like theWritingbranch. This is a cherry-pick of #5156, and it applied cleanly.moq-net's
Writerresets on drop unless closed, so today's moq-net callers do not hit this path. It is still a contract bug in the adapter.2. A priority REQUEST_UPDATE did not move group streams already in flight (moq-net)
#5133 applies a priority-only REQUEST_UPDATE to the track subscription and acknowledges it. But each
GroupServecaptured its priority once, so an open stream (a long group, or one blocked on flow control) kept the old priority.TrackServenow owns the priority in akiochannel that every group stream follows while open: it is applied at open, while serving, and while waiting for the FIN acknowledgement. Lite already does the same for SUBSCRIBE_UPDATE. This is a backport of #5162; I re-applied it by hand because the surrounding code differs on release.I considered refusing priority updates instead. That would end a subscription over a benign update, and the fix is small, so I applied the update fully instead.
Public API and wire impact
None. Everything touched is private. On the wire, a FIN that was promised now goes out instead of a reset, and an acknowledged priority update now applies to open streams too.
Tests
a_deferred_finish_survives_a_drop_mid_watch(moq-tokio, paused time): fails without fix 1.subscription_update_reprioritizes_open_group_streams(moq-net, paused time, draft-22): fails without fix 2 (the open stream stays at send order 127) and passes with it.unacknowledged_fin_follows_priority_updates(moq-net): a stream parked on its FIN acknowledgement follows two successive updates. Mirrored from fix(net): move open IETF group streams on a priority update #5162's review follow-ups, along with its comments.just check origin/releaseon 55089ca: exit 0 (the main Rust run: 5026 passed).cargo nextest run -p moq-net: 1522 passed.cargo nextest run -p moq-tokio: 432 passed.just checkagainstorigin/release: exit 0. A first run hadmoq-tokio::broadcast broadcast_race_quic_winsfail onAddrInUsewhile binding its server, a local port collision; the rerun passed everything.just test bare-fin: both tests pass.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code