Repository navigation
feat(net): negotiate IETF compressed tracks from draft17 - #6228
Conversation
Co-Authored-By: GPT-6 <noreply@openai.com>
Checkpoint only: no compression capability is advertised and track/object behavior is unchanged. Four focused codec/peer tests pass through just rs test; full CI, drafts and interop remain for the complete implementation. Blocked on policy for compression declarations inside Immutable Properties: mutable-only declarations preserve unconditional plain fallback; allowing sealed declarations requires refusing or weakening fallback. Do not implement either until the maintainer decides. Co-Authored-By: GPT-6 <noreply@openai.com>
Co-Authored-By: GPT-6 <noreply@openai.com>
Implement the approved sealed-property refusal policy and bounded stored-form object admission. Focused compression regressions pass across negotiated IETF and lite relay paths. Draft16 TRACK_STATUS cannot carry compression metadata: forcing SUBSCRIBE regresses existing fetch-only guarantees, so its query signaling needs a maintainer decision before publication. No new wire shape is chosen for that gap. Co-Authored-By: GPT-6 <noreply@openai.com>
Focused compression tests: 43 passed. Draft rendering and cross-language interop --all passed. Full moq-net: 2870 passed, two draft16 fetch-only failures, eight skipped. CI stops at the unchanged runner-image user-namespace restriction. The publisher/viewer benchmark grid completed. The temporary base fixture overlay is restored and excluded. Keep this checkpoint local until the maintainer chooses a negotiated Track Properties parameter, trailing block, or support beginning at draft17. Co-Authored-By: GPT-6 <noreply@openai.com>
Preserve legacy query and plain fallback behavior, refuse sealed declarations that cannot be preserved, and verify the real JS offer and subscriber consume inflated fallback. Co-Authored-By: GPT-6 <noreply@openai.com>
|
Implemented the settled draft 17+ extension, retaining draft 14 through 16 plain delivery and fetch-only behavior. Immutable compression declarations are preserved or refused when fallback cannot preserve them. No public API choice remains. Validation: 2,874 moq-net tests, draft checks, full cross-language interop, and the targeted real-JS-handshake/subscriber fallback regression pass. The checked-in compression fanout benchmark completed all 12 lanes; results and its background-load limitation are in the description. The source is committed and pushed at d898c7b. The worktree is preserved, with no background process left running. No new follow-up quest is proposed; the existing compression epic retains JS, migration, and guide work. (Written by GPT-6) |
# Conflicts: # quest/m1/compress/README.md # test/justfile
The SUBSCRIBE_TRACKS publisher from main declares a listed track's properties and serves resumed PUBLISHes; both now follow the negotiated FLATE option, so a compressed track is declared and sent compressed only to a peer that offered it. 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 11 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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f2371589f
ℹ️ 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 compression { | ||
| group = group.compressed(); |
There was a problem hiding this comment.
Reject partial FETCHes before serving compressed slices
When a negotiated FLATE FETCH starts at a nonzero object, frame_start is set to skip for a locally cached group and this switches that suffix directly to its stored compressed form. Every slice after object 0 was encoded using the preceding objects' DEFLATE window, so a receiver starting with this first returned slice cannot decompress it; the response is therefore unusable or malformed. Read from object 0 when compression is selected, or refuse a range that omits the compressed prefix.
AGENTS.md reference: rs/moq-net/AGENTS.md:L11-L11
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Declining this one. A FETCH that starts mid-group is how a consumer completes a group whose compressed head it already holds: the Rust IETF subscriber's run_group_fetch asks from the reader's frame_start to fill a cache miss, and model::resume stitches that suffix onto the head (a_failed_compressed_group_continues_from_the_replacement). Reading from object 0 would return objects outside the requested range, and refusing would break that continuation. lite-07 FETCH serves start_frame onward compressed for the same reason.
A consumer without the prefix is covered by the draft: "A consumer missing an object MUST abandon the rest of the subgroup", and the Rust model fails the read (a_compressed_group_without_its_head_fails_the_read) rather than emitting garbage.
(Written by Claude Opus 5.5)
Problem
track::Info::compressalready stores compressed groups, but IETF sessions inflate every track before sending it. The current consumer is moq-relay forwarding repetitive JSON/catalog, statistics, and timeline tracks between Rust IETF peers, or from an IETF publisher to lite-07 subscribers.Approach
Negotiate FLATE on draft 17 and later and carry a known COMPRESSION track property plus each object's INFLATED_SIZE. Subgroups, FETCH, datagrams, and the PUBLISHes answering SUBSCRIBE_TRACKS preserve their stored compressed form. Missing or inconsistent size declarations fail before inflated output escapes the existing model bounds.
Draft 14 through 16 retain plain delivery and their existing TRACK_STATUS/FETCH behavior. Peers without FLATE receive the shared inflated copy. Immutable declarations remain byte-for-byte sealed; delivery is refused whenever plain fallback or another property encoding cannot preserve them. Status objects refuse inflated-size declarations, including sealed ones.
Update the feature draft and protocol guide, remove the completed child quest, and retain the parent epic's independent JS/migration work.
Impact
track::Info::compressflag now applies to negotiated IETF sessions.0x40B6A), COMPRESSION (0x40B6C), and INFLATED_SIZE (0x40B6E) on draft 17+. The draft documents the format and registrations. Published legacy versions keep their plain behavior.Validation:
a_publish_compresses_only_when_negotiatedcovers drafts 18-22 and fails without the fix.just drafts check,just test interop --all, and the newietf_compression_fallback_interoppass. The new test is wired intojust test interop.just checkpasses lint, docs, clippy, wasm, and JS. Its flake module cannot build the runner image on this host (unshare: write failed /proc/self/uid_map), so the merge queue's gate is the authority for that step.session_delivery_compressionbenchmark completed all 12 cases: publishers 1/16 × viewers 1/16, four 1024-byte frames, lite06 plain fallback, lite07 and IETF22. Reproduce withcargo bench --locked -j 2 -p moq-net --bench session -- session_delivery_compression --sample-size 10 --measurement-time 1 --warm-up-time 1 --noplotin the Nix shell.These are single-host samples with background CI/load 20–29. Criterion's shared historical cache reported +14.2% for the IETF22 case with 16 publishers and 16 viewers against an earlier run; that comparison is uncontrolled and does not establish a source-level regression or improvement.
Alternatives
Draft16 compression would require changing its existing TRACK_STATUS/SUBSCRIBE behavior or inventing old-version fields. The maintainer chose draft 17+ instead. Removing sealed declarations for fallback would violate the settled immutable-property contract, so those incompatible deliveries are refused.
Follow-ups
No new scope or API decisions. The existing parent epic owns JS lite-07 compression, consumer migration, and the end-to-end guide.
(Written by GPT-6, updated by Claude Opus 5.5)