Repository navigation
feat(net): a cold moq-transport copy resolves relative anchors from its live join - #7283
Conversation
Quest-Claim: 42e0d0d161cfca46
…ts live join A moq-transport copy that cannot settle a relative anchor from its cache joins live instead of refusing it, and resolves the anchor once the Largest Object or a newer group names the live edge. The resolved bounds go upstream as an absolute update. Time anchors the cache cannot settle stay refused. Rewrites quest/m1/subscribe-ranges/lite.md to the remaining range fill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gest A live join's Largest becomes the copy's live edge, and the deferred upstream bounds resolve before the alias admits any data stream, so a newer group landing first cannot move either resolution. 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 35 minutes. View limit details
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 |
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. |
|
Landing. Maintainer decision (2026-10-30): merge this slice. The quest keeps the lite-07 range fill. Codex reviewed (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 809095c150
ℹ️ 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".
| if let Ok(mut state) = self.modify() | ||
| && let Feed::Live { first, edge } = &mut state.feed | ||
| { | ||
| *edge = (*edge).max(Some(group)); | ||
| first.get_or_insert(group); |
There was a problem hiding this comment.
Preserve the answered edge when resuming an idle copy
When a returning subscriber requests Relative(2) on an idle moq-transport copy, subscribe_once defers resolution, but this guard discards the answer's Largest because the feed is still Feed::Idle. If Largest names group 4 and group 5 arrives before group 4, the resume loop's set_live calls go_live, which initializes first from the newest produced group, 5. Both the reader and the deferred upstream bounds then resolve the start to 3 instead of 2, silently omitting requested history. Preserve the answered anchor across the idle-to-live transition without making stale cached data readable prematurely. This also violates the warm/cold upstream-state invariant in rs/moq-net/AGENTS.md.
AGENTS.md reference: rs/moq-net/AGENTS.md:L8-L8
Useful? React with 👍 / 👎.
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 809095c150568af26c6a2377c188867ca5f210c5.
- P2, existing independent finding: I confirmed the idle-copy anchor loss at
rs/moq-net/src/model/track.rs:3387-3391, already reported here; no duplicate inline comment.report_edgeignoresFeed::Idle, and the resume path subsequently callsset_liveafter a newer group arrives.go_livetakes the maximum of that group and the answered edge, so Largest=4 followed first by group 5 makesRelative(2)start at 3 rather than 2. Preserve the answered anchor across resume while retaining the stale-cache readability gate, and cover the idle/resume case.
Direction: resolving to absolute bounds through the existing range resolver is a sensible, contained alternative to introducing another relative wire mapping. The fresh-copy ordering fix is present, but the same invariant needs to cover resumed copies. No additional actionable bugs found in the changed paths.
Verification: static review of the diff, subscription/update flow, model feed transitions, and changed tests. I did not run tests or independently verify the reported CI results.
(Written by OpenAI)
Problem
A Rust moq-transport copy refused a
Relative(n)anchor whenever its cache couldn't settle it yet, e.g. a cold relay copy asked forRelative(2)... The maintainer's 2026-10-27 decision says a bridge never sends a relative anchor upstream. Instead it resolves the anchor to an absolute Group ID from its cache or from the live edge before sending, and a cold copy should do that from a live join's Largest Object rather than refuse.Approach
rs/moq-net/src/ietf/subscriber.rs): when the aggregate's ranges can't be resolved yet and carry no time anchor, the SUBSCRIBE goes out as the live join instead of being refused. After SUBSCRIBE_OK, the anchor resolves against the answer's Largest. This happens beforeregister_aliaslets any data stream in, so a newer group that lands first can't shift it. The resolved bounds go upstream as an ordinary absolute update. If the answer has no Largest, or a later demand change is still unresolved, the loop waits for the next group (settle_bounds) instead of aborting the copy.rs/moq-net/src/model/track.rs): newProducer::report_edge. It records a live join's answered Largest asFeed::Live.edge(andfirstif not yet set), so the copy's readers count relative starts back from it.refuse_cached_anchorsnow refuses only an unresolved time anchor; a relative one waits for the live edge, as on lite-07.rs/moq-net/tests/integration/range_anchors.rsnow expects moq-transport-18 and -22 to read every relative case (open and bounded) as the held track does. They are compared sorted because the backfill below the live group arrives after it. Ordered reads belong to read-backfill.doc/concept/moq-lite.mdandtrack::Anchordescribe the new behavior.quest/m1/subscribe-ranges/lite.mdis rewritten to the work that remains, the lite-07 range fill through the subscription. Links inlite07-finalize.mdand the epic README are updated.Choices made without asking:
report_edgeapplies to every live join with a Largest, not only deferred ones, so the copy's readers and the upstream resolve from the same edge.Impact
report_edgeis crate-private).Relative(n)(n ≥ 1) or a relative end now gets data instead ofUnsupported.Validation
At 809095c:
quest gate just ci origin/main: passes (9050 Rust tests and the JS suites).quest gate just test interop --all: all checks pass (run at 431e0e2, before the follow-up fix, which touches only IETF copy resolution).model::track::test::a_relative_start_counts_from_the_answered_edge: fails withoutreport_edge(Unsupported) and passes with it.quest check --base origin/main: 669 documents OK.Decisions
/quest-starttakes it from there.Review
quest review --base origin/main, quest pinned at01d051cf5d).report_edge, resolution before the alias is bound, and a regression test.Follow-ups
subscribe_join), but an update on the same wire carries an absolute end. That predates this PR, but means a warm and a cold copy differ for absolute bounded ranges on draft-18. Worth a/quest-planlook.Quest: quest/m1/subscribe-ranges/lite.md
🤖 Generated with Claude Code
(Written by Claude Opus 5.5)