Repository navigation
feat(net)!: datagrams are unfetchable and bounded by the group range - #4982
Conversation
|
Outcome: quest implemented and left as a draft. All local checks pass (just check, nextest, js/net bun test, drafts check, interop --all). The two open decisions are listed in the description: (Written by Claude Opus 5.5) |
43d88f9 to
381f2b3
Compare
381f2b3 to
c06902b
Compare
|
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 7 minutes. View limit detailsLimit details: You’ve used all 4 included reviews currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (22)
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 |
A subscription takes only the datagrams pushed after it opened, through whichever copy of the track reaches it, and its group range bounds them the way it bounds groups. A draft-16+ fetch object flagged as a datagram fails only that fetch, as a group that does not exist. 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>
A datagram-flagged fetch object now fails the fetch or fill with a new Error::NotFetchable instead of NotFound. On the wire it goes out as the code a group that does not exist gets: IETF DOES_NOT_EXIST and moq-lite NOT_FOUND, matching what a publisher that never cached the datagram says. moq-ffi folds it into MoqError::NotFound; the relay HTTP fetch and HLS export treat it as a miss (404). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A FETCH that reached a datagram resets with 0x3A NOT_FETCHABLE on lite-07; earlier lite versions keep NOT_FOUND, IETF keeps DOES_NOT_EXIST. An origin that still buffers the datagram answers NotFetchable instead of NotFound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c06902b to
36fc65f
Compare
|
Grok review of The live-only rule looks right in the model. Stamping each buffered datagram with a process-wide tick and opening each relay copy "since" the reader's tick closes the front/splice gap, and the per-version NOT_FETCHABLE/NOT_FOUND mapping is consistent on encode, decode, relay hops, and the IETF DOES_NOT_EXIST bridge. I couldn't find a lite path that sends a code without going through Non-blocking
Verdict: MERGE once CI is green. Item 1 is a narrow path (a pre-draft-20 IETF upstream that puts datagram objects in a joining fetch), so it's fine as a follow-up. This is an automated review, not the maintainer's decision |
A datagram object among an absolute joining FETCH's groups failed the whole fill, aborting the complete group before it and dropping the groups after. The join now finishes that head and skips the datagram; any other fill or a group fetch still refuses it as NotFetchable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Re the Grok review of (Written by Claude Opus 5.5) |
|
Grok follow-up review of This push is one commit, Earlier findings
Non-blocking
Verdict: MERGE once CI is green. This is an automated review, not the maintainer's decision |
…end buffer Strict live-only datagram delivery is not a goal: a new subscriber may read the datagrams still in the track's send buffer, as before. Removes model::datagram::Tick, Consumer::subscribe_since and the opened-at plumbing, reverts moq-c's open-before-return change, and rewords the docs and draft. The group range still bounds datagrams and FETCH still never returns one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Grok follow-up review of This push is one commit, The revert is clean. Earlier findings
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: 85d0158, including the latest tick-removal change.
Direction: the narrowed contract is coherent: ranges bound datagrams, FETCH does not return them, and replay remains permitted. The version-gated 0x3A mapping and binding/HTTP miss handling are consistent. No additional issue from removing the tick plumbing.
Confirmed the two existing absolute-join edge cases in #4982 (comment); both remain at this head:
- [P2] rs/moq-net/src/ietf/subscriber.rs:3258 checks the presence of the wire Group ID. A second datagram object inheriting its group therefore aborts the join and loses subsequent stream groups. Use the resolved/effective prior_group and test two datagram objects between stream groups.
- [P2] :3262 calls end_fill_group even when a draft-16/17 datagram belongs to the current head's own group. The helper at :3907 marks that partial head complete. Compare effective sequences first and abort an unrepresentable mixed group rather than caching it as complete.
No duplicate inline comments added. Verification: full original diff, current twenty-two-file patch, latest commit, relevant fill/group-resolution context, and discussion inspected. Static review only; no tests or independent CI verification. GitHub currently reports a merge conflict.
…roup Resolves the append_datagram doc conflict with untimed tracks (#4822) and stamps the datagram fetch/alias tests now that a timed track refuses an unstamped object. Review fixes on the absolute-join datagram skip: judge the datagram by its resolved Group ID, so a later object inheriting a datagram group's ID is skipped too instead of failing the join, and refuse a datagram inside the head's own group as NotFetchable rather than finishing the partial head. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Re the OpenAI review of
Merge skew from untimed tracks (#4822): the datagram fetch/alias tests now stamp their objects on a timed track. (Written by Claude Opus 5.5) |
|
Grok follow-up review of This push merges Earlier findings
Non-blocking
Verdict: MERGE once CI is green. This is an automated review, not the maintainer's decision |
|
Re the Grok review of (Written by Claude Opus 5.5) |
Completes
quest/m1/datagram-unfetchable.md(deleted here), minus its "a new subscription never replays buffered datagrams" rule, which the maintainer dropped (decision 2).Problem
A group range did not bound datagrams, and a datagram-flagged IETF fetch object failed with
Unsupported. Nothing said a FETCH can never return a datagram.Approach
@moq/net). The cursor's floor and cap filter datagrams as they filter groups. A start frame above 0 drops the start group's datagram (its only frame). A datagram is judged when the reader reaches it, against the range in force then. An out-of-range one is dropped for good, never parked like a group past the cap.main. No tick, no age bound (decisions 2 and 11).Error::NotFetchable, checked before any payload is read. An absolute joining FETCH, which spans whole groups, instead finishes the group before the datagram, skips every object of the datagram group (judged by its resolved Group ID), and keeps filling the groups after it. A datagram inside the head's own group is refused asNotFetchableand the partial head aborted.NotFetchableinstead ofNotFound. Past the buffer, or on a relay whose upstream answers, a miss staysNotFound.draft-lcurley-moq-lite: Datagrams section (range bound, never cached or fetched, a new subscription MAY get the send buffer), NOT_FETCHABLE row, moq-lite-07 changelog bullets.doc/concept/moq-lite.mdanddoc/concept/standard.mdupdated.Impact
StreamError::Unknownthere. No change to published versions.moq_net::Error::NotFetchable("A FETCH reached a datagram, which is never cached.") andmoq_net::StreamError::NotFetchable(the received/sent lite code). A received 0x3A surfaces asError::Stream(StreamError::NotFetchable), matching how NOT_FOUND surfaces asError::Stream(StreamError::NotFound).Error::NotFetchableintoMoqError::NotFound, and a receivedStreamError::NotFetchablereportsMoqProtocolKind::NotFound(moq-cMOQ_PROTOCOL_KIND_NOT_FOUND) with the verbatim code 0x3A.@moq/net). Late-subscriber replay is unchanged frommain.lite::Version::has_not_fetchableispub(crate).Decisions
Maintainer (2026-10-07):
Error::NotFetchable, notNotFoundorUnsupported.model::datagram::Tick,Consumer::subscribe_since, and the opened-at plumbing throughresume. (Supersedes the earlier "keep the process-wide datagram tick".) Rejected: the process-wide tick; per-subscription buffer indices.moq-lite-07-wiponly; earlier lite versions keep NOT_FOUND; IETF keeps DOES_NOT_EXIST. (Supersedes the earlier "map onto existing codes" choice.)@moq/netNotFetchable mirror yet (deferred until JS gains an IETF fetch receive path).Made while iterating (recommended option picked; open to challenge):
Error::Stream(StreamError::NotFetchable), not the flatError::NotFetchable, matching every other registry code (Error::from_transportnests codes received from a peer). Consumers match both forms, as they already do for NotFound.NotFetchable.fromTransportwraps it asStream(code)), so 0x3A is not added toStreamCodehere; it belongs with the JS follow-up.max_delayof the newest datagram's timestamp (existing machinery, a few lines); or a wall-clock age. No in-repo consumer (hang, moq-mux) reads datagrams, each datagram carries its timestamp for the application to judge, and this ismain's behavior today. A sparse track can replay up to 64 old datagrams to a late joiner; revisit with themax_delaystart if one needs it.moq_consume_datagrams: it closed a race only live-only delivery created.Tests
Model:
a_datagram_group_is_not_fetchable(nowNotFetchable, and a non-datagram miss staysNotFound),the_group_range_bounds_datagrams,a_mid_group_start_drops_the_start_groups_datagram,a_range_update_applies_to_buffered_datagrams. Codes:not_fetchable_is_lite_07s(lite-05/06 encode NOT_FOUND and leave 0x3A unknown; lite-07 round-trips), the lite registry round-trip and relay-hop tests, and the IETF stream/request registry sweeps (EVERY_ERROR,unregistered_conditions_are_internal, DOES_NOT_EXIST for both forms). End to end (tests/datagram.rs,a_fetched_datagram_is_refused_per_version): lite-05 and lite-06 get NOT_FOUND, lite-07 gets NOT_FETCHABLE, and through a relay lite-07 to lite-07 stays NOT_FETCHABLE while lite-07 to lite-06 becomes NOT_FOUND. IETF:a_group_fetch_refuses_a_datagram_object,an_absolute_join_skips_a_datagram_group(a two-object datagram group),an_absolute_join_refuses_a_datagram_in_the_head,a_datagram_fill_fails_only_the_fill,a_datagram_before_its_alias_is_dropped,a_standalone_fetch_of_a_datagram_group_is_refused. moq-hls:NotFetchableis a cache miss locally and over lite. JS:the group range bounds datagrams.Checks:
just check origin/maingreen at 03529eb (lint, clippy, 5309 Rust tests, JS, Python). After mergingmaina5d8d89: nextest on moq-net, moq-c, moq-ffi, moq-hls, moq-relay and clippy on moq-net green.just drafts checkpasses.just test interop --allpassed before the tick removal, which changes no wire.Follow-ups
@moq/netdiffer on late-subscriber replay: Rust's shared track buffer hands a new subscriber up to 64 buffered datagrams, while JS's per-subscriber buffers hand it none. Both satisfy the rule; feat(js/net): carry datagrams over moq-transport as OBJECT_DATAGRAM #4979 (JS IETF datagrams) should not promise either.NotFetchablethere, and name 0x3A inStreamCode, to mirror Rust.@moq/nethas no start-frame field, so the mid-group datagram rule only exists in Rust. Fold it into the JS IETF datagram quest if JS gains frame starts.fetch_groupwithUnsupported, so the end-to-end datagram FETCH test cannot cover moq-transport hops; the IETF publisher tests cover DOES_NOT_EXIST instead.🤖 Generated with Claude Code
(Written by Claude Opus 5.5)