From 37194f14e13c5746fd734c3ec27b6192d502ae7c Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Fri, 9 Oct 2026 19:01:20 -0700 Subject: [PATCH 1/2] quest: plan the second release backport batch and the parked-read bench budget Follow-ups from the 2026-10-09 release backport triage: a questline for the smaller release-only fixes left out of the first batch, a quest for the track_parked_read bench outliving its budget, and a note that the IETF request-header fix needs a release backport too. Co-Authored-By: Claude Opus 5.5 --- quest/m1/README.md | 2 ++ quest/m1/ietf-dispatch-headers.md | 3 ++ quest/m1/parked-read-bench-budget.md | 16 +++++++++++ quest/m1/release-backports/README.md | 30 ++++++++++++++++++++ quest/m1/release-backports/catalog-floor.md | 14 +++++++++ quest/m1/release-backports/fetch-fin.md | 17 +++++++++++ quest/m1/release-backports/js-fin.md | 14 +++++++++ quest/m1/release-backports/namespace-fill.md | 14 +++++++++ quest/m1/release-backports/request-params.md | 15 ++++++++++ quest/m1/release-backports/setup-repeat.md | 12 ++++++++ 10 files changed, 137 insertions(+) create mode 100644 quest/m1/parked-read-bench-budget.md create mode 100644 quest/m1/release-backports/README.md create mode 100644 quest/m1/release-backports/catalog-floor.md create mode 100644 quest/m1/release-backports/fetch-fin.md create mode 100644 quest/m1/release-backports/js-fin.md create mode 100644 quest/m1/release-backports/namespace-fill.md create mode 100644 quest/m1/release-backports/request-params.md create mode 100644 quest/m1/release-backports/setup-repeat.md diff --git a/quest/m1/README.md b/quest/m1/README.md index cd8e8a09d7..c603472428 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -66,6 +66,7 @@ ladders. - [Media audio-tone check](/quest/m1/media-audio-tone.md) - the media lane's audio-tone check passes under load, fixed at its cause - [More tests under load](/quest/m1/test-flakes-2/README.md) - the second round of load-only failures, one quest per flake, fixed at the cause - [Test TypeScript check](/quest/m1/test-ts-check.md) - `just check` type-checks the TypeScript harnesses under test/ +- [Release backports, second batch](/quest/m1/release-backports/README.md) - the 0.17.x line picks up the smaller release-only fixes left from the 2026-10-09 triage - [IETF request headers](/quest/m1/ietf-dispatch-headers.md) - each bidi request reads its header in its own task, so a slow one never blocks the next - [END_OF_TRACK placement](/quest/m1/ietf-end-of-track-placement.md) - END_OF_TRACK rides the upstream's Location, and Rust's header stops claiming END_OF_GROUP - [moq-uring tests under load](/quest/m1/uring-tests-under-load.md) - uring tests pass while parallel checks share locked memory @@ -131,6 +132,7 @@ ladders. - [Perf](/quest/m1/perf/README.md) - eliminate measured hot-path costs across moq-uring, kio, and the moq-net model - [#2924](/quest/m1/2924-moq-relay-tls-rotation-is-not-atomic-across-thread-per.md) - every listener on both runtimes shares one reloadable served identity, so rotation is atomic and generate works with workers - [Benchmark regressions in CI](/quest/m1/bench-ci.md) - PRs get a non-blocking comparison of the Criterion benches they affect, and a nightly trend on main alerts on regressions +- [Parked-read bench budget](/quest/m1/parked-read-bench-budget.md) - `track_parked_read` completes at default settings instead of expiring its parked reads mid-warm-up - [Mergeable bench buckets](/quest/m1/bench-buckets.md) - moq-bench emits per-interval latency buckets that sum across processes and hosts - [Relay session bench](/quest/m1/bench-relay.md) - the same scenario through moq-relay's own connection handling - [Session burst hang](/quest/m1/session-burst-hang.md) - the burst sweep completes at 16 subscriptions and 16+ groups per round diff --git a/quest/m1/ietf-dispatch-headers.md b/quest/m1/ietf-dispatch-headers.md index 223125d9b2..9a019dbf74 100644 --- a/quest/m1/ietf-dispatch-headers.md +++ b/quest/m1/ietf-dispatch-headers.md @@ -21,4 +21,7 @@ this is Rust only (decided 2026-10-08). Test, beside #5086's `a_silent_stream_does_not_hold_up_the_next`: a silent bidi request stream does not block a SUBSCRIBE on the next one. +`release` has the same loop; once this lands on `main`, backport it the way +#5125 carried the uni half. + Public API: none. Wire: none. diff --git a/quest/m1/parked-read-bench-budget.md b/quest/m1/parked-read-bench-budget.md new file mode 100644 index 0000000000..f020737a4d --- /dev/null +++ b/quest/m1/parked-read-bench-budget.md @@ -0,0 +1,16 @@ +# [XS] track_parked_read never outlives its budget + +## Goal + +`rs/moq-net/benches/track.rs`'s `track_parked_read` completes at default +Criterion settings on any machine, instead of panicking once warm-up runs +long enough for parked reads to expire. + +## Plan + +Found while benchmarking #5159 (2026-10-09): each append advances timestamps +by 2.5 ms, so a warm-up past about 1.44M iterations crosses the bench's 3600 s +age budget and the parked reads expire, panicking at the bench's assertion. +It fails on unchanged `main`; whether it hits depends on machine speed. Size +the budget or the timeline to the iteration count (or reset state per batch) +so the measured path stays the parked one. diff --git a/quest/m1/release-backports/README.md b/quest/m1/release-backports/README.md new file mode 100644 index 0000000000..a16b6602f2 --- /dev/null +++ b/quest/m1/release-backports/README.md @@ -0,0 +1,30 @@ +# Release backports, second batch + +## Goal + +The 0.17.x line picks up the remaining fixes from the 2026-10-09 backport +triage that were left out of the first batch, each as its own PR onto +`release` (CONTRIBUTING), or the quest is deleted once a fix proves unneeded. + +## Plan + +The first batch (#5120 through #5135, plus #5164) covered every crash, leak, +and interop break the triage found. These children are smaller release-only +patches; most can't cherry-pick because `main` built them on work `release` +lacks (#4741, #4268, #4658's `request_stream.rs`). Write the release patch +against release's own code, carry the original regression test, and confirm +it fails on `release` first. Interop at Seattle (2026-10-12) may raise or +drop each one's priority. + +The `release` interop matrix only negotiates moq-lite, so IETF changes need +unit tests or `just test bare-fin`-style coverage rather than `just test +interop`. + +## Required + +- [FETCH survives a request FIN](/quest/m1/release-backports/fetch-fin.md) - a d19+ FETCH keeps serving after the requester FINs, as SUBSCRIBE does since #5133 +- [Repeated unknown SETUP options](/quest/m1/release-backports/setup-repeat.md) - a peer repeating an unknown or GREASE SETUP option no longer closes the session +- [Unknown request parameters](/quest/m1/release-backports/request-params.md) - draft 14-17 peers sending FORWARD or an unlisted parameter no longer close the session +- [NAMESPACE fill on d16+](/quest/m1/release-backports/namespace-fill.md) - a d16+ SUBSCRIBE_NAMESPACE without SOLICIT still gets NAMESPACE entries +- [JS keeps requests alive after FIN](/quest/m1/release-backports/js-fin.md) - the release-line `@moq/net` publisher stops cancelling on a d19+ request FIN +- [Quiet catalog after a cleared floor](/quest/m1/release-backports/catalog-floor.md) - a relay serves a quiet catalog after a resume floor clears, if the stall reproduces on `release` diff --git a/quest/m1/release-backports/catalog-floor.md b/quest/m1/release-backports/catalog-floor.md new file mode 100644 index 0000000000..2795ce0e72 --- /dev/null +++ b/quest/m1/release-backports/catalog-floor.md @@ -0,0 +1,14 @@ +# [S] Quiet catalog after a cleared resume floor on release + +## Goal + +On `release`, a relay that resumes a broadcast after a reconnect serves its +catalog even when the catalog track is quiet and the resume floor has been +cleared, or this quest is deleted because the stall does not reproduce there. + +## Plan + +#4940 (`35fa44f6b`) fixed the stall on `main`. Triage suspected `release` +has it too (spliced `start_at` only raises) but did not prove it. Reproduce +first with a release-side test; port only if it fails. The publisher half of +#4940 applied cleanly; the resume and track halves need adapting. diff --git a/quest/m1/release-backports/fetch-fin.md b/quest/m1/release-backports/fetch-fin.md new file mode 100644 index 0000000000..3d4e34b7c9 --- /dev/null +++ b/quest/m1/release-backports/fetch-fin.md @@ -0,0 +1,17 @@ +# [S] A d19+ FETCH survives a request FIN on release + +## Goal + +On `release`, a FETCH or joining FETCH on draft 19+ keeps serving after the +requester FINs its side of the request stream; a reset or STOP_SENDING still +cancels it, and drafts 14-18 keep cancelling on FIN. + +## Plan + +#5133 gated SUBSCRIBE and SUBSCRIBE_NAMESPACE with `fin_cancels` in +`rs/moq-net/src/ietf/request_stream.rs` and left FETCH alone. Apply the same +gate to the FETCH paths in the IETF publisher, with a version-swept test like +`requester_fin_is_version_gated_for_subscriptions`. Check whether `main`'s +FETCH path already behaves this way; if not, land it there first. + +Raise its priority if a Seattle peer FINs after FETCH. diff --git a/quest/m1/release-backports/js-fin.md b/quest/m1/release-backports/js-fin.md new file mode 100644 index 0000000000..5f1b7ee892 --- /dev/null +++ b/quest/m1/release-backports/js-fin.md @@ -0,0 +1,14 @@ +# [S] Release-line JS keeps requests alive after FIN + +## Goal + +The release-line `@moq/net` publisher keeps serving a draft 19+ subscription +after the requester FINs its request stream, matching the Rust publisher +since #5133; drafts 14-18 still cancel on FIN. + +## Plan + +#4658 changed both languages on `main`; #5133 ported only Rust. Port the JS +publisher half to `js/net/src/ietf/` on `release`, with a version-swept test, +and bump `@moq/net` on `release` after it lands (`/bump`). Matters when a +browser publishes through a draft 19+ peer that FINs after SUBSCRIBE. diff --git a/quest/m1/release-backports/namespace-fill.md b/quest/m1/release-backports/namespace-fill.md new file mode 100644 index 0000000000..e8a98a638b --- /dev/null +++ b/quest/m1/release-backports/namespace-fill.md @@ -0,0 +1,14 @@ +# [S] NAMESPACE fill on d16+ on release + +## Goal + +On `release`, a draft 16+ SUBSCRIBE_NAMESPACE from a peer that does not send +SOLICIT still receives NAMESPACE entries for matching broadcasts, instead of +an empty stream. + +## Plan + +#5032 (`d5208239f`) fixed this on `main` on top of #4268's active counts. +For `release`, apply the solicitation filter only on drafts 14 and 15. Worth +doing if a Seattle peer discovers broadcasts through NAMESPACE rather than +unsolicited PUBLISH_NAMESPACE; otherwise this can be deleted. diff --git a/quest/m1/release-backports/request-params.md b/quest/m1/release-backports/request-params.md new file mode 100644 index 0000000000..a6f1f1fffd --- /dev/null +++ b/quest/m1/release-backports/request-params.md @@ -0,0 +1,15 @@ +# [S] Unknown request parameters on release + +## Goal + +On `release`, a draft 14-17 peer that sends FORWARD on SUBSCRIBE_NAMESPACE, or +any unlisted request parameter on drafts 14 and 15, keeps its session instead +of closing it with InvalidValue. + +## Plan + +#5028 (`4bf8b59cd`) fixed this on `main` by reworking `decode_params!`, which +depends on main-only macro syntax and `request_stream.rs`. Write the minimal +release patch: accept FORWARD where drafts 15-17 allow it, and skip unknown +keys where drafts 14 and 15 say to ignore them. moqx on draft 16 is the known +peer that hits this; it redials in a loop today. diff --git a/quest/m1/release-backports/setup-repeat.md b/quest/m1/release-backports/setup-repeat.md new file mode 100644 index 0000000000..c541cfb976 --- /dev/null +++ b/quest/m1/release-backports/setup-repeat.md @@ -0,0 +1,12 @@ +# [XS] Repeated unknown SETUP options on release + +## Goal + +On `release`, a moq-transport peer that repeats an unknown or GREASE SETUP +option completes the handshake instead of failing with `Duplicate`. + +## Plan + +Backport only the SETUP half of #4927 (`4b53bd27d`): unknown option kinds may +repeat, known ones still refuse duplicates. Skip #4927's stricter GROUP_ORDER +validation, which tightens behavior rather than fixing a break. From 5e04a33f57e73cfb4ab10d3f262aeeaa0b5272d8 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 10 Oct 2026 05:45:43 -0700 Subject: [PATCH 2/2] quest: release has request_stream.rs; keep interop --all; FETCH gate is release-only Co-Authored-By: Claude Opus 5.5 --- quest/m1/release-backports/README.md | 22 +++++++++++--------- quest/m1/release-backports/fetch-fin.md | 9 ++++---- quest/m1/release-backports/request-params.md | 5 +++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/quest/m1/release-backports/README.md b/quest/m1/release-backports/README.md index a16b6602f2..1bc2a2b4b1 100644 --- a/quest/m1/release-backports/README.md +++ b/quest/m1/release-backports/README.md @@ -8,17 +8,19 @@ triage that were left out of the first batch, each as its own PR onto ## Plan -The first batch (#5120 through #5135, plus #5164) covered every crash, leak, -and interop break the triage found. These children are smaller release-only -patches; most can't cherry-pick because `main` built them on work `release` -lacks (#4741, #4268, #4658's `request_stream.rs`). Write the release patch -against release's own code, carry the original regression test, and confirm -it fails on `release` first. Interop at Seattle (2026-10-12) may raise or -drop each one's priority. +The first batch (#5120 through #5135, plus #5164, some still landing) covers +every crash, leak, and interop break the triage found. These children are +smaller release-only patches; most can't cherry-pick because `main` built them +on work `release` lacks (#4741, #4268, main's `decode_params!` syntax). +`release` does have `rs/moq-net/src/ietf/request_stream.rs` since #5133, with +`fin_cancels` and `poll_cancel`; extend it rather than writing around it. +Write the release patch against release's own code, carry the original +regression test, and confirm it fails on `release` first. Interop at Seattle +(2026-10-12) may raise or drop each one's priority. -The `release` interop matrix only negotiates moq-lite, so IETF changes need -unit tests or `just test bare-fin`-style coverage rather than `just test -interop`. +The `release` interop matrix only negotiates moq-lite, so IETF changes also +need unit tests or `just test bare-fin`-style coverage. Still run `just test +interop --all`, as AGENTS.md requires for wire changes. ## Required diff --git a/quest/m1/release-backports/fetch-fin.md b/quest/m1/release-backports/fetch-fin.md index 3d4e34b7c9..bb253b5eb8 100644 --- a/quest/m1/release-backports/fetch-fin.md +++ b/quest/m1/release-backports/fetch-fin.md @@ -9,9 +9,10 @@ cancels it, and drafts 14-18 keep cancelling on FIN. ## Plan #5133 gated SUBSCRIBE and SUBSCRIBE_NAMESPACE with `fin_cancels` in -`rs/moq-net/src/ietf/request_stream.rs` and left FETCH alone. Apply the same -gate to the FETCH paths in the IETF publisher, with a version-swept test like -`requester_fin_is_version_gated_for_subscriptions`. Check whether `main`'s -FETCH path already behaves this way; if not, land it there first. +`rs/moq-net/src/ietf/request_stream.rs` and left FETCH alone: release's +`run_fetch_stream` paths still watch `stream.reader.poll_closed` directly. +`main` already routes its FETCH paths through `request_stream::poll_cancel`, +so this is release-only. Do the same on `release`, with a version-swept test +like `requester_fin_is_version_gated_for_subscriptions`. Raise its priority if a Seattle peer FINs after FETCH. diff --git a/quest/m1/release-backports/request-params.md b/quest/m1/release-backports/request-params.md index a6f1f1fffd..af4f913e7d 100644 --- a/quest/m1/release-backports/request-params.md +++ b/quest/m1/release-backports/request-params.md @@ -9,7 +9,8 @@ of closing it with InvalidValue. ## Plan #5028 (`4bf8b59cd`) fixed this on `main` by reworking `decode_params!`, which -depends on main-only macro syntax and `request_stream.rs`. Write the minimal -release patch: accept FORWARD where drafts 15-17 allow it, and skip unknown +depends on main-only macro syntax. Release's `request_stream.rs` (from #5133) +differs from main's, so adapt that part rather than cherry-picking it. Write +the minimal release patch: accept FORWARD where drafts 15-17 allow it, and skip unknown keys where drafts 14 and 15 say to ignore them. moqx on draft 16 is the known peer that hits this; it redials in a loop today.