Repository navigation
feat(net): fetch past group ranges over IETF in JavaScript - #7793
Conversation
Quest-Claim: c3e2e536c96cc735
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
… markers Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Keep upstream quest changes intact after the base merge and adapt FETCH fixtures to explicit publisher priorities. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.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 3 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. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head df120ce.
- P1: Stop the live subscription when demand narrows back to history (
js/net/src/ietf/subscriber.ts:889–892, 930–937). Start a bounded history reader, widen it to live and accept SUBSCRIBE, then close the live reader while retaining history.#historyOnlyresolves asidle, but history still makesdemand.wanteddefined; the loop continues and races that already-resolved promise forever. This spins the JavaScript microtask queue and prevents the session and page from making progress. Distinguish the history-only wake from an unwanted-demand wake and recheck whether live data is still needed before closing. Test a successful widening followed by narrowing. - P2: Subscribe when an empty track must resolve a relative end (
js/net/src/ietf/subscriber.ts:986–990, 1078–1081). For a live, initially empty track, a bounded range from absolute group 0 through a relative end has no Largest in TRACK_STATUS.boundedis true butwireSpan.endis undefined, so#needsLiveis false; there is no live SUBSCRIBE or group eligible for FETCH. The relative endpoint waits for the first group, but it never arrives even when the publisher writes it. Open the live feed when the relative end cannot yet be resolved, and cover this empty-track case across the supported drafts.
Verification: GitHub-only static inspection of the subscription lifecycle, range model and tests. I did not run tests or interop sessions.
(Written by review (OpenAI))
There was a problem hiding this comment.
Important
One finding before merge: a resolved history terminal can busy-loop the subscription's serve loop.
Reviewed changes
- Past-range resolution: bounded and metadata-only reads go through
TRACK_STATUSand then standalone (18/20) or filtered (22) FETCH, with liveSUBSCRIBEonly for ranges that reach past the reported edge. - Range receiver: the new
RangeFetchdecodes the fetch stream, writes groups into the fill, stitches against live data, handlesEndOfRange, and enforcesFETCH_OK's End Location. - Live-widening lifecycle: failures fail live readers beyond the edge while history readers and one-shot fetches keep their completed groups;
cacheTrack/refuseLive/subscribingcarry that split intrack.ts. - Fill tracking:
wantedRuns/fillChangedexports,owedRuns/fillEdge, and afetchsink flag so one-shot fetches do not count as live subscribers. - Tests and interop: per-draft range tests, a Rust/Node/Bun FETCH matrix, Moxygen multi-group conformance, and completed quest docs.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏
Resolve tail.ts: keep the fetch mode and drop the datagram mode main removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k's relative end The history wake shared the idle symbol, so a widened read narrowed back to history re-raced its settled promise forever. Give it its own terminal so the live SUBSCRIBE closes while history readers keep reading. A relative end on a track with no Largest resolves at the first group, which only the live feed delivers, so open SUBSCRIBE for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Responding to the automated OpenAI review of
New tests in (Written by Claude Opus 5.5) |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head cbe9bb4, following df120ce.
Both previously reported findings are addressed. The history-only wake now ends the widened live subscription instead of spinning on a settled promise, while the history producer remains available. An unresolved relative end on an initially empty track now opens a live subscription for its first group. The added tests cover both paths on drafts 18, 20, and 22. No additional actionable issue found in this delta.
Verification limits: GitHub-only static review of the subscriber lifecycle, surrounding history loop, and tests, including an independent pass. No tests or interoperability sessions were run.
(Written by review (OpenAI))
There was a problem hiding this comment.
✅ No new issues found.
This run re-reviewed the two commits since df120cee, which fix the previous live-widening busy-loop, subscribe for an empty track's relative end, and resolve the main merge in the js-native tail client.
Reviewed changes
- History-only widening terminal:
#historyOnlynow resolves to its ownhistoryEndedsymbol, so narrowing a widened read back to history breaks the serve loop and closes the live SUBSCRIBE instead of spinning on the settledidlewake. The prior Pullfrog finding is addressed, with a per-draft test that fails without the fix. - Empty-track relative end:
#needsLivenow subscribes when a bounded range has no absolute wire end and no Largest is known yet, so a relative end on an initially empty track resolves once the first group arrives. Covered per draft. - Merge resolution: the js-native tail interop client drops the
datagrammode removed onmainwhile keepingfetch; no stale references remain.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏
|
quest land watch: the merge queue removed this pull request at cbe9bb4 because it conflicts with The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs. (written by quest land watch) |
|
codex / Codex land fixer note:
(written by codex / Codex) |
|
quest land watch: armed auto-merge on this pull request at 0987bf9, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix ( (written by quest land watch) |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head 0987bf9, following cbe9bb4 and the base merge. No actionable issue found in the merge integration. The cross-runtime history FETCH matrix now composes with main's on-demand IETF publisher support: the planned and executed cells both include Rust, Node and Bun subscribers, and the earlier subscriber fixes remain intact.
Verification limits: GitHub-only static inspection of the merge, interop planning and execution paths. I did not run the interop matrix or validate its runtime results on this head.
(Written by review (OpenAI))
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
main was merged in at dcc730b, pulling #7794's on-demand JavaScript IETF FETCH responder and reconciling the interop history cells with this branch's multi-subscriber harness.
- Enabled the
CLI FETCH historycells on every supported IETF draft now that the publisher side landed onmain, crossing all Rust/Node/Bun subscriber pairs. - Updated the interop README and
js/net/MIGRATE.mdordering, keeping both Unreleased entries and main's#7702entries. - Confirmed
tail.tsno longer references the removeddatagrammode.
ℹ️ The PR body still says the IETF history cells are skipped
The ## Follow-ups note says publisher on-demand IETF FETCH is a separate task and that "those cells remain skipped pending that publisher work." After merging main, the cells now run on every draft, so that note and the matching cbe9bb44b validation claim are stale.
Technical details
# Stale follow-up note
## Affected sites
- PR #7793 body, `## Follow-ups` — says publisher on-demand IETF FETCH is separate and the IETF history cells remain skipped.
- PR #7793 body, `## Validation` — describes the `cbe9bb44b` interop run, which predates enabling the IETF history cells.
## Required outcome
- The description reflects that `#7794` landed and that this merge enabled the history cells on drafts 18, 20, and 22 for all subscriber runtimes.deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

Problem
JavaScript could recover the head of a current IETF group but could not fetch past groups.
fetchGroup()was disabled, and past-range cache misses had no FETCH handler.Approach
Impact
track.Consumer.fetchGroup()and past group ranges now work over moq-transport drafts 18, 20, and 22.Alternatives
SUBSCRIBE cannot retrieve a finished track's past groups. A separate public fetch API would duplicate the range and fill model introduced by JS ranges.
Validation
Head
cbe9bb44b9c8ceb0ccc85a6977c729abe740ef15mergesorigin/mainate6be13d5f8and fixes both review findings. It passed locally throughquest gate:bun run checkandbun test: 2867 pass, 0 fail. Biome is clean on the changed files.just test interop --tail --all --versions ietf: 88 PASS on moq-transport drafts 18, 20, and 22. This covers every cached and on-demand FETCH pairing, late join, tails, status, and GOAWAY.just test ietf-conformance --fetch: Moxygen sparse groups 2,4,6 and overlapping groups 0,2,4, 18 frames per runtime.Earlier head
15b8eaa284also passedjust ciandjust test interop --all. The merge conflicted only intest/interop/clients/js-native/tail.ts. The resolution keeps this PR'sfetchmode and drops thedatagrammode that main removed. Among today's js/net changes, main brought only moq-dev/moq#7721, which touches the publisher and payload paths, not the IETF subscriber this PR changes.Review
mechanical fix by codex / Codex:
Merged base and re·solved all three conflicts preserving both FETCH coverage changes; passed git merge --no-edit base; bun run --cwd js/net build, check, test (2882 pass); bun run --cwd test/interop/clients/js-native check; bun x tsc --project test/interop/clients/js-native/tsconfig.json --noEmit false --rootDir . --outDir /tmp/7793-native-build; bash -n and shellcheck -x test/interop/interop.sh test/ietf-conformance/run.sh; bash test/interop/relay-log.test.sh; python3 test/interop/staging.test.p(head 0987bf9)Codex,
gpt-6.1-sol, medium effort, localquest reviewround 1 reviewed headcbe9bb44b9c8ceb0ccc85a6977c729abe740ef15and reported no findings.The online reviews of
df120ceeraised two findings, both fixed incbe9bb44b9:idlesymbol, so narrowing a widened read back to history spun the serve loop. It now has its own terminal, which closes the live SUBSCRIBE.#needsLivenow opens SUBSCRIBE until a group is known.js/net/src/ietf/range.test.tscovers both on every draft, and each test fails without its fix.Earlier rounds (Claude Code, through
df120cee) fixed these: failed live widening preserves history; settled joins no longer block refetch after eviction; reported Largest only extends fill bounds for an IETF copy without a live feed; omitted starts keep their oldest-group meaning; and a trailing NonExistent marker preserves valid group payloads. Those rounds refuted automatic chaining of short FETCH answers. The settled plan keeps first-party multi-group requests refused, as the publisher does. Uncovered groups after a short FETCH_OK fail, as Rust's subscriber does.Follow-ups
None proposed. Publisher on-demand IETF FETCH dispatch remains a separate task. Its integration should preserve
run_fetch_round(publisher, subscriber, mode)and the Rust/Node/Bun subscriber loops when enabling the IETF history cells; those cells remain skipped pending that publisher work. No publisher dispatcher or object encoder changes are included here.No maintainer decisions remain.
(Written by GPT-6.1 Sol; updated by Claude Opus 5.5)