diff --git a/quest/m0/broadcast-epoch/README.md b/quest/m0/broadcast-epoch/README.md index 4af74ffe27..8652959cd7 100644 --- a/quest/m0/broadcast-epoch/README.md +++ b/quest/m0/broadcast-epoch/README.md @@ -101,4 +101,5 @@ maintainer's pre-release merge of `release` into `main` keeps `main`'s - [Publish catalog restart](/quest/m0/broadcast-epoch/publish-catalog-restart.md) - `@moq/publish` never reuses catalog group numbers under one name and epoch after a re-announce - [Bindings](/quest/m0/broadcast-epoch/bindings.md) - moq-ffi and every wrapper expose the epoch and let a publisher announce one - [moqsrc](/quest/m0/broadcast-epoch/moqsrc.md) - moqsrc switches to the new broadcast on a `Restart`, keeping its pads by rendition name +- [Follow gap](/quest/m0/broadcast-epoch/follow-gap.md) - a followed path reports a gap that ended its request, even onto a same-epoch covering prefix - [Stats totals and prefix tracks](/quest/m0/broadcast-epoch/stats-split.md) - the same release retires the per-path stats maps for totals and on-demand prefix tracks (decided 2026-10-05) diff --git a/quest/m0/broadcast-epoch/follow-gap.md b/quest/m0/broadcast-epoch/follow-gap.md new file mode 100644 index 0000000000..638676535c --- /dev/null +++ b/quest/m0/broadcast-epoch/follow-gap.md @@ -0,0 +1,34 @@ +# [S] A followed path reports a gap that ended its request + +## Goal + +`origin::Consumer::follow` reports a gap that ended the request (an `End` +then `Start`, or a `Restart`) even when the next serving route is a covering +prefix with the same epoch, so `moq play` never misses a handoff while it is +still draining the old run. + +## Plan + +Found by the OpenAI review of #5154 (2026-10-10), which added `follow` in +moq-net and `@moq/net`. A same-epoch handoff from the exact route to a +covering prefix, after a gap that ended the old request, reaches the Rust +follower as an `Update`, because the announce cursor delivers by prefix and +the follower never sees the gap. If that `Update` arrives while `moq play` is +draining the old run, playback never restarts. JS sees the gap and is +correct. + +Decided 2026-10-10: merge #5154 and fix the cause in moq-net here, in m0 +because the epoch line gates the release. Rejected: re-requesting in +`moq play` whenever a run fails while the path is still served, which loops +tightly on a broadcast that fails every time. + +Fix it in the announce cursor or the follower so the gap surfaces, matching +JS. Regression with simulated time: an exact route ends, its request ends, +then a same-epoch prefix route takes over while a reader is still draining; +the follower must report the handoff, and `moq play` must restart. Leave the +follower unpolled until the replacement is announced, since awaiting its +`End` first avoids the bug and passes on the broken code, as +`follow_keeps_a_gap_between_routes_of_one_epoch` does today. + +Public API: no new items, but `follow` reports a gap where it reported an +`Update`, a behavior change to call out in the PR. Wire: none.