From b9447f5970bd04e5cd0ff0e2a7c1704ca4be6077 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Fri, 30 Oct 2026 12:31:23 -0700 Subject: [PATCH] quest: plan the release backport of #7135's joined-head FETCH race fix Co-Authored-By: Claude Opus 5.5 --- quest/m0/README.md | 1 + quest/m0/backport-fill-head-race.md | 40 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 quest/m0/backport-fill-head-race.md diff --git a/quest/m0/README.md b/quest/m0/README.md index 8c3f4064763..1f1a64586aa 100644 --- a/quest/m0/README.md +++ b/quest/m0/README.md @@ -26,5 +26,6 @@ edge, which embeds moq-relay; it moved there on 2026-09-28. - [Release shutdown backport](/quest/m0/ffi-shutdown-backport.md) - `release` publishes a non-breaking moq-ffi with an async `drain()` and qmux sessions on the QUIC stream limit - [Backport audio groupDuration](/quest/m0/backport-audio-group-duration.md) - `@moq/publish` 0.5.4 on `release` can pack several Opus frames per group, making Cloudflare's relay drop audio less often - [Backport the SETUP-path and iroh-key fixes](/quest/m0/backport-security-fixes.md) - `release` refuses a conflicting SETUP Path and keeps persisted iroh keys private, in one patch release +- [Backport the joined-head FETCH race fix](/quest/m0/backport-fill-head-race.md) - a `release` relay stops FETCHing a group head its own SUBSCRIBE is bringing, which left live readers hanging - [CI cost and latency](/quest/m0/ci/README.md) - cloud CI runs only in a batched merge gate as one `just ci` pass per batch, expensive checks run nightly and gate `release`, caches move to R2, and runners are chosen last - [More tests under load](/quest/m0/test-flakes-2/README.md) - load-only and queue failures, one quest per flake, fixed at the cause, since each one fails a whole batch diff --git a/quest/m0/backport-fill-head-race.md b/quest/m0/backport-fill-head-race.md new file mode 100644 index 00000000000..999fed9f17f --- /dev/null +++ b/quest/m0/backport-fill-head-race.md @@ -0,0 +1,40 @@ +# [M] Backport the joined-head FETCH race fix to release + +## Goal + +A relay on `release` no longer FETCHes the head of a group that its own +SUBSCRIBE is already bringing. In that race the fetched objects can land first, +so the relay caches the group as fetched, refuses the live tail stream that ends +it as `duplicate`, and leaves live readers waiting on the group until they time +out. This ports fix 2 of +[moq-dev/moq#7135](https://github.com/moq-dev/moq/pull/7135) and ships it in a +`moq-net` patch release. + +## Plan + +Decided 2026-10-30 (maintainer): port only the relay fix. Why: #7135's other +fix, the JS publisher answering an `INCLUDE_PROPERTIES=0` FETCH without +timestamps, cannot happen on `release`, whose `js/net/src/ietf/publisher.ts` +`runFetch` refuses every FETCH. + +Decided 2026-10-30 (maintainer): m0, beside the other `release` backports. +Why: it is an intermittent relay hang on the shipped line. + +`release` has the same machinery as main before #7135: the joining-head +`Fill` in `rs/moq-net/src/ietf/subscriber.rs` and the group FETCH that fills a +cache miss (`run_group_fetch`). It has no `rs/moq-net/src/model/track/fill.rs`, +so the fix is hand-ported, not cherry-picked. Port the behavior: a cache miss +for the joined group waits until the subscription's own head arrives or its +request settles, then the cache answers it; a failed head request still falls +back to a FETCH. Only that group waits, so older history still FETCHes at once, +and the wait ends when no reader wants the group or the track aborts. Port +#7135's subscriber tests that cover this alongside it. + +Start by reproducing the race on `release` with one of those tests. If +`release` cannot hit it, delete this quest and say why in the PR. + +Public API: none. Wire: none. + +## Required + +- [The browser backend baseline completes on IETF22](/quest/m0/nightly/browser-baseline.md) - lands the fix this quest ports, on main