Repository navigation
fix(tokio): keep a deferred FIN when a send stream drops mid-watch - #5156
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>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 40 minutes. View limit detailsLimit details: You’ve used all 4 included reviews currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Grok review of 8a91d0d Small, targeted fix: the No blocking issues. Non-blocking:
Verdict: MERGE (once CI is green) This is an automated review, not the maintainer's decision |
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. |
|
Merge summary for 8a91d0d The Reviews on this head: Codex finished with a thumbs-up and no findings; Grok had no blockers. CI is green. On Grok's non-blocking notes, I'm leaving the code as is:
The release backport #5164 cherry-picks this fix and is handled separately. Enabling squash auto-merge pinned to this head. (Written by Claude Opus 5.5) |
Codex found this on the release backport #5133.
mainhas the same code, so this PR fixes it here first.The bug
Since #4658,
moq-tokio's wrappedSendStream::poll_closedstarts the realclosed()watch on an idle, unfinished stream (SendState::Closing), and that future owns the stream. Iffinish()is called while the watch holds the stream, the FIN is only recorded as deferred and the watch is interrupted. If the stream is then dropped before another poll,Drop'sClosingbranch rescued only a deferred reset. It dropped the future, so the backend did its default drop reset instead of the FIN thatfinish()had already reported as successful.Before #4658,
Closingwas reached only afterfinish/reset, so no FIN could be deferred there.moq-net's ownWriterresets on drop unless closed, so today's moq-net callers do not hit this. It is still a contract bug in the adapter.Fix
The
Closingdrop branch now reclaims the interrupted watch and applies a deferred finish as well as a deferred reset, the same way theWritingbranch already does.Public API and wire impact
None.
Tests
a_deferred_finish_survives_a_drop_mid_watch(paused time). It fails without the fix ("the deferred FIN was lost") and passes with it.cargo nextest run -p moq-tokio: 451 passed.just check: everything else passes, butmoq-cli publish::tests::ts_passthrough_crosses_a_relay_through_a_flagged_jumpfails (moq-transport-14, "both copies crossed"). It is a wall-clock test, and it fails the same way on unmodifiedmainwhen its sibling tests run alongside it. It passes when run alone.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code