Repository navigation
feat(net): MoQ Active Count for IETF namespace subscriptions - #4268
Conversation
Adds the MoQ Namespace Count extension (draft-lcurley-moq-namespace-count): when both sides declare the NAMESPACE_COUNT Setup Option on draft-16+, the REQUEST_OK answering SUBSCRIBE_NAMESPACE says how many NAMESPACE messages replay the initial set, so the announce Live marker fires on the count instead of the quiet timer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It mirrors moq-lite's AnnounceOk.active: the count is of the active namespaces a SUBSCRIBE_NAMESPACE replays. Wire values are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-count # Conflicts: # quest/m1/js-origin-scope.md
…where The draft counts the NAMESPACE messages before a subscription is caught up rather than namespaces, and no longer leans on moq-lite. A REQUEST_OK carrying ACTIVE_COUNT in answer to anything but SUBSCRIBE_NAMESPACE is a protocol violation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The subscriber is caught up after reading Count NAMESPACE messages; the publisher only has to send exactly that many first. Also covers a counted OK to a REQUEST_UPDATE. 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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 96c060280b
ℹ️ 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".
| } | ||
| ietf::solicit::into_setup(&mut parameters, ietf_encoding); | ||
| ietf::hidden::into_setup(&mut parameters, ietf_encoding); | ||
| ietf::active_count::into_setup(&mut parameters, ietf_encoding); |
There was a problem hiding this comment.
Implement Active Count in js/net in this change
When a Rust endpoint connects to @moq/net, this declaration cannot become bilateral because the TypeScript setup and REQUEST_OK handling remain unchanged, so Rust-JS sessions still use the quiet-timer path instead of Active Count. The newly added quest/m1/js-active-count.md explicitly defers the matching implementation, but wire changes must update js/net in the same change; add the TypeScript negotiation, publisher, subscriber, and interop coverage here.
AGENTS.md reference: rs/moq-net/AGENTS.md:L5-L5
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Deferring on purpose. The extension is opt-in and only negotiated when both sides declare it, so Rust-JS sessions keep today's quiet-timer behavior with no wire break. The JS subscriber can't use the count until the per-source guard from #4261 (js-announce-caught-up) lands, so the TypeScript side is tracked in quest/m1/js-active-count.md rather than half-implemented here.
(Written by Claude Opus 5.5)
Decisions
(Written by Opus 5.5) |
# Conflicts: # quest/m1/README.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67f111ea2f
ℹ️ 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 msg.active.is_some() { | ||
| return Err(Error::ProtocolViolation); |
There was a problem hiding this comment.
Close the session for nested active-count violations
When a draft-15 peer uses solicited namespace discovery, this branch runs inside run_subscribe_namespace_stream; Publisher::handle_stream catches and only logs every error from that task. Therefore, an ACTIVE_COUNT on a PUBLISH_NAMESPACE or update response ends only that subscription stream instead of closing the session with PROTOCOL_VIOLATION, contrary to drafts/draft-lcurley-moq-active-count.md:84. Propagate this protocol violation to the session driver or explicitly close the session rather than letting the request-task wrapper swallow it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Agreed, fixed in 6b08c19: both the PUBLISH_NAMESPACE and REQUEST_UPDATE violation sites now close the session with PROTOCOL_VIOLATION before returning, and the two violation tests assert the close.
(Written by Claude Opus 5.5)
On the draft-15 solicited path, advertise_namespace runs inside a request task that only logs errors, so the violation ended one stream instead of the session the draft requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge summary
(Written by Claude Opus 5.5) |
Problem
An IETF session has no way to say where the NAMESPACE messages answering a SUBSCRIBE_NAMESPACE stop covering what the publisher already advertises and start reporting changes, so the announce
Livemarker waits for the stream to go quiet (500 ms when empty, 30 ms after the last entry).Approach
drafts/draft-lcurley-moq-active-count.md: an ACTIVE_COUNT Setup Option (0x40B64), negotiated when both sides declare it, and an ACTIVE_COUNT parameter (0x40B66) on the REQUEST_OK answering SUBSCRIBE_NAMESPACE, giving the number of NAMESPACE messages that come before the subscription is caught up. Only declared on draft-16+, which has NAMESPACE.Impact
Tests
tests/caught_up.rsnow runs under paused time and asserts counted versions (moq-transport-16/19 added) catch up without waiting out the quiet gap, while quiet ones (moq-transport-14/15, lite-03/04) do, with three routes and with none. Fails on draft-16 with the declaration disabled.the_ok_counts_only_what_is_advertised: an unforwardable suffix is left out of the count.a_count_the_negotiation_did_not_promise_is_a_violation,a_counted_publish_namespace_ok_is_a_violation, anda_counted_update_ok_is_a_violation, plus a REQUEST_OK round trip.Alternatives
Follow-ups
quest/m1/js-active-count.md:@moq/netspeaks the extension oncejs-announce-caught-uplands the per-source guard it needs. Until then JS never declares the option, so Rust keeps the timer against it.(Written by Opus 5.5)
🤖 Generated with Claude Code