Repository navigation
Conversation
…bsence moq-transport marks no end to a SUBSCRIBE_NAMESPACE's initial set unless both sides declare MoQ Active Count, so its discovery syncing with no route proves nothing. A plain request covered by such a session took Unroutable at REQUEST_OK, so a relay that serves by origin pull and announces nothing was unplayable. Count only sessions that prove absence toward that sync; the rest answer plain requests with a direct SUBSCRIBE, as one without discovery does. moq-lite, Active Count peers, and follow() are unchanged. 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. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 3f371c1
P2 — Restrict blind answers to the eligible session (js/net/src/origin.ts:927–930, consumed by connection/forward.ts's serveRequests). proven < total enables every session's serving loop, not just the peer that cannot prove absence. Attach a counted/lite session A first and an uncounted moq-transport pull-only session B to one origin, with neither announcing the requested path. A's loop can claim the sole slot.answer first even though only B serves that path; B then skips the occupied slot, and subscribing to A fails instead of pulling through B. This newly supported combination of two discovering peers needs per-session eligibility as well as the aggregate check. Gate blind answering by the session's current proof/downgrade state (preserving discovery-refusal fallback), and add a mixed-session regression that ensures only B consumes the path.
Direction: separating discovery from proof of absence is the right, narrowly scoped approach; the capability must also constrain answer selection. The single-session tests cover the intended behavior and follower isolation, but not this mixed-session case.
Verification: static inspection of the changed accounting, negotiated Active Count, blind answer selection/cleanup, and tests, with independent confirmation of the mixed-session path. I did not run tests or browser/relay interoperability checks.
|
Sorry this breaks with multiple connections and CDNs. The JS code was like this but it caused a bunch of issues compared to the Rust code. Publish a namespace so I know you're a publisher. Don't make me guess and blindly send a SUBSCRIBE to every connection and hope one of them supports it. |
Problem
Since #6445 (and #7173), a plain
Origin.Consumer.request(path)on a session whose peer accepted discovery failsUnroutableonce that discovery has synced with no route for the path. A moq-transport session reads as synced the moment SUBSCRIBE_NAMESPACE is answered: the protocol marks no end to the initial set, so without MoQ Active Count the subscriber treats REQUEST_OK as the boundary. A relay that accepts SUBSCRIBE_NAMESPACE but serves tracks by origin pull, announcing nothing until a SUBSCRIBE triggers the pull, is therefore unplayable: the request ends before it ever subscribes. Published @moq/net 0.4.5 subscribed directly. #3532 already cites a draft-16 relay that doesn't announce.The drafts make the direct SUBSCRIBE legal and give no way to prove absence:
Consumer: @moq/watch with
announced="false"(a plain request) against IETF moq-transport relays that don't announce.Approach
A session now reports internally whether its discovery can prove absence. moq-lite always can (ANNOUNCE_OK's count or SYNCED). moq-transport can only when both sides declare MoQ Active Count. The origin counts those sessions separately. A plain request settles
Unroutableon synced absence only when every session proves absence. Otherwise the session that cannot answers it blind, with a direct SUBSCRIBE, exactly as a session without discovery already does. The SUBSCRIBE's own outcome decides from there: a refusal such as does-not-exist ends the track with that error.Unroutableunchanged.follow()still never takes a blind answer.Verified in Chrome with
@moq/watchagainst an IETF moq-transport relay that accepts SUBSCRIBE_NAMESPACE and announces nothing until a SUBSCRIBE pulls the track: withannounced="false", CMAF plays on drafts 22 and 18; withannounced="true", it still waits for an announcement, sending no SUBSCRIBE.Impact
Consumer.discoverykeeps its value. Behaviour fix forrequest()on moq-transport peers without MoQ Active Count.Unroutable. A forward test pins the later-announcement switch. The existing feat(net)!: own broadcast discovery during resolution #6445 Unroutable test is unchanged.Alternatives
discoveryand @moq/watch's announced gate for relays that do announce. Rejected as broader.Follow-ups
rs/moq-net/src/ietf/subscriber.rs), so Rustrequestlikely needs the same fix.Refs #3532, #6445, #7173.
(Written by Claude Opus 5.5)
🤖 Generated with Claude Code