-
-
Notifications
You must be signed in to change notification settings - Fork 248
docs(quest): plan follow-ups from the next-16 quest wave #4140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # [M] Paced replay | ||
|
|
||
| ## Goal | ||
|
|
||
| A live player plays a replayed recording unchanged: `moq import archive` | ||
| publishes each recorded track to SUBSCRIBE as well as FETCH, pushing its groups | ||
| when a shared clock reaches their media time, like `ffmpeg -re`. `export ts` | ||
| and web watch play a replay the way they play a live broadcast, and a viewer | ||
| who joins late joins mid-replay. | ||
|
|
||
| ## Plan | ||
|
|
||
| - Today `moq_archive::Reader` publishes only the timeline track live and serves | ||
| media groups on FETCH through `track::Dynamic`, so a subscriber sees none. | ||
| - One clock per import, not per subscriber. It starts at the earliest recorded | ||
| timestamp across the selected tracks and every track paces against it, so | ||
| tracks stay in sync and every viewer sees the same moment. | ||
| - A timeline gap is skipped at pace (the clock keeps running). A growing | ||
| archive is followed as new timeline segments land. A finite archive ends | ||
| each track after its last group. | ||
|
Comment on lines
+18
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The archive contract explicitly has no completion marker ( Useful? React with 馃憤聽/ 馃憥. |
||
| - FETCH keeps serving any advertised group, so DVR and HLS are unaffected. | ||
| - The API shape (a reader option vs a separate paced publisher) and the CLI | ||
| default follow the root API rules; report both in the PR. Update | ||
| `doc/bin/cli.md`. | ||
| - Test with paused time: record, replay paced, and assert a plain subscriber | ||
| gets every group in order at media pace, that a late subscriber starts at the | ||
| current group, and that two tracks stay aligned. | ||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The functional test with two tracks does not cover the feature's two fan-out axes. A shared pacing implementation could scan every track per tick or repeat pacing work per subscriber without this test detecting the resulting slope. Add a benchmark sweeping selected-track count and concurrent subscriber count so the shared-clock design is verified to scale with the touched path. AGENTS.md reference: AGENTS.md:L35-L35 Useful? React with 馃憤聽/ 馃憥. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # [S] Replay provenance | ||
|
|
||
| ## Goal | ||
|
|
||
| The catalog a replay publishes carries the root `archive` entry the line | ||
| promises: the timeline track, the replay path, the store URL, and the format | ||
| version. A player or tool can tell a replay from the live source and find the | ||
| recording. | ||
|
|
||
| ## Plan | ||
|
|
||
| - Check which of these fields `rs/hang` and `js/hang` already define. Add any | ||
| missing ones as optional fields in both, and in the Recording section of | ||
| `drafts/draft-lcurley-moq-hang.md`. | ||
| - Never advertise credentials: strip userinfo and query from the store URL, and | ||
| let the importer opt out of advertising the URL at all. | ||
| - `moq import archive` fills the entry. Test that a round trip through | ||
| `export archive` and `import archive` advertises it. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # [XS] Kotlin end | ||
|
|
||
| ## Goal | ||
|
|
||
| Kotlin can force-end a broadcast after `finish` is removed. Its | ||
| `MoqBroadcastProducer` exposes the moq-ffi `close()` as `end()`, because a | ||
| generated `close()` would collide with `AutoCloseable.close()`. | ||
|
|
||
| ## Plan | ||
|
|
||
| - Rename the method for Kotlin only in `rs/moq-ffi/uniffi.toml`; every other | ||
| binding keeps `close()`. Kotlin's `close()` still only releases the handle. | ||
|
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
AGENTS.md reference: AGENTS.md:L64-L67 Useful? React with 馃憤聽/ 馃憥. |
||
| - Test that `end()` ends the broadcast while a `dynamic()` handle is still | ||
| held. Document it in `doc/lib/kt`. | ||
|
|
||
| ## Required | ||
|
|
||
| - [Binding close](/quest/m1/broadcast-close/bindings.md) - moq-ffi gains the `close()` this renames | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # [S] Import discontinuity | ||
|
|
||
| ## Goal | ||
|
|
||
| A publisher that seeks or pauses tells its importer so, and the flush jitter | ||
| measurement restarts instead of counting the break. `moqsink` does it on a | ||
| seek, and C and FFI publishers can do it too. | ||
|
|
||
| ## Plan | ||
|
|
||
| - `moq_mux::container::Producer::discontinuity()` already resets the flush | ||
| baseline (`catalog/estimate.rs`). `import::Track` gains a `discontinuity()` | ||
| that forwards to it, and the codec importers without one gain it too. Only | ||
| the baseline resets; advertised values are never lowered. | ||
| - `moqsink` calls it when a pad re-anchors after a flush or a new segment | ||
| (`rs/moq-gst/src/sink/pad.rs`). Test that a seek on an `encoder` pad does | ||
| not raise the advertised jitter. | ||
|
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
A plain AGENTS.md reference: AGENTS.md:L16-L18 Useful? React with 馃憤聽/ 馃憥. |
||
| - Expose it as `moq_publish_media_discontinuity` in libmoq and as | ||
| `discontinuity()` in moq-ffi and its hand-written wrappers, per the | ||
| Cross-Package Sync table. This is additive, so it lands on `main`. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # [S] JS bare FIN | ||
|
|
||
| ## Goal | ||
|
|
||
| A `@moq/net` subscriber aborts a track whose subscribe stream FINs before the | ||
| publisher declared its end, over moq-lite and IETF, as Rust does since #4083. | ||
| A bare FIN is a failed request, never a clean end. | ||
|
|
||
| ## Plan | ||
|
|
||
| - The drafts agree: draft-19 section 3.3.2 treats a FIN before the required | ||
| messages (PUBLISH_DONE) as a failure, and the moq-lite draft has a publisher | ||
| FIN only after SUBSCRIBE_END. | ||
| - Abort with the error Rust uses, so both languages report the same thing. Add | ||
| an interop case where a publisher FINs without declaring an end, in both | ||
| directions. | ||
|
|
||
| The clean-end path this tightens landed in #4086. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # [M] Tests hold up under load | ||
|
|
||
| ## Goal | ||
|
|
||
| Three tests that pass alone but fail under a full `just check` pass reliably, | ||
| fixed at the cause rather than by raising a timeout or adding a retry: | ||
|
|
||
| - `js/json/src/snapshot/snapshot.test.ts:359`, "a compressed delta is gated | ||
| on its encoded size", which takes about 4.3 s against a 5 s limit. | ||
| - The `js/net/src/declarations.test.ts` test that times out at 5 s. | ||
| - `rs/moq-tokio/tests/backend.rs:739` `noq_cert_reload`, which fails with | ||
| "Too many open files". | ||
|
|
||
| ## Plan | ||
|
|
||
| - Find why each JS test is slow. It should shrink its input or reveal a real | ||
| slowdown in the code under test; fix whichever it is. | ||
| - For `noq_cert_reload`, find what holds the descriptors: a leak in the test | ||
| or code under test, or nextest parallelism against the file limit. Fix a leak | ||
| at its source, and otherwise cap the test's concurrency in | ||
| `.config/nextest.toml`. | ||
| - Prove it by running `just check --all` several times on a loaded machine. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,17 +4,17 @@ | |
|
|
||
| Writing an AudioSpecificConfig for a channel count that no AAC | ||
| channelConfiguration names is an error, not a stereo config with a warning, | ||
| in `moq_mux::codec::aac::Config::encode` and `@moq/hang`'s | ||
| `audioSpecificConfig`. This mirrors the parse side, which since #4093 refuses | ||
| reserved values instead of guessing stereo. | ||
| in `moq_mux::codec::aac::Config::encode`, as `@moq/hang`'s | ||
| `audioSpecificConfig` already refuses since #4119. This mirrors the parse | ||
| side, which since #4093 refuses reserved values instead of guessing stereo. | ||
|
Comment on lines
+7
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
AGENTS.md reference: AGENTS.md:L16-L17 Useful? React with 馃憤聽/ 馃憥. |
||
|
|
||
| ## Plan | ||
|
|
||
| Both functions become fallible, a published API break in each language, so | ||
| this targets `dev`. Counts with a PCE-free configuration map as today. For | ||
| the others, either write channelConfiguration 0 with a PCE derived from the | ||
| layout, or refuse. Pick one at PR time and apply it in both languages. Test | ||
| every count from 1 to 8 and one beyond. | ||
| `Config::encode` becomes fallible, a published API break, so this targets | ||
| `dev`. Counts with a PCE-free configuration map as today. Refuse the others, | ||
| matching JS; writing channelConfiguration 0 with a PCE derived from the layout | ||
| is a later additive change in both languages. Test every count from 1 to 8 and | ||
| one beyond. | ||
|
|
||
| ## Related | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # [XS] Archive refuses backward timestamps | ||
|
|
||
| ## Goal | ||
|
|
||
| A resumed recording refuses a track whose timestamps go backward past the | ||
| recovered timeline, failing loud like the group-ID check, instead of writing | ||
| overlapping media time. The caller starts a new prefix. | ||
|
|
||
| ## Plan | ||
|
|
||
| Check the first group's timestamp against the recovered track's last recorded | ||
| timestamp at enrollment, and test both a backward and a forward restart. | ||
|
|
||
| ## Required | ||
|
|
||
| - [Archive](/quest/m1/archive/README.md) - the recovery this hardens ships with the line |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # [M] Archive recovery listing | ||
|
|
||
| ## Goal | ||
|
|
||
| A DVR writer resuming a recording lists storage in proportion to what changed | ||
| since its last checkpoint, not every stored `groups/` object, while still never | ||
| deleting a referenced object. | ||
|
|
||
| ## Plan | ||
|
|
||
| - Recovery today reconciles a complete `groups/` listing of every recorded | ||
| track before accepting input. Compare bounding it with an ordered | ||
| `list_with_offset` from the oldest retained range, with orphans below it left | ||
| to a background sweep, against a checkpointed listing marker. | ||
| - Benchmark recovery time and requests over archive size before and after. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Benchmarking only over aggregate archive size cannot establish the stated proportional-to-change behavior. An implementation can still rescan all retained history or all tracks while looking acceptable when only one combined size varies. Hold the post-checkpoint delta fixed while growing retained history, then grow the delta independently, and sweep track count as the other fan-out axis so a full-table slope is visible. AGENTS.md reference: AGENTS.md:L35-L35 Useful? React with 馃憤聽/ 馃憥. |
||
|
|
||
| ## Required | ||
|
|
||
| - [Archive](/quest/m1/archive/README.md) - the recovery this bounds ships with the line | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # [S] Expired token error | ||
|
|
||
| ## Goal | ||
|
|
||
| A session whose token expired reports `moq_net::Error::Expired`, not | ||
| `Unauthorized`, over moq-lite and moq-transport, mirrored in `@moq/net` and | ||
| the bindings. A client can then refresh its token instead of treating the | ||
| refusal as final. | ||
|
|
||
| ## Plan | ||
|
|
||
| - Add the variant to the `#[non_exhaustive]` error, so the change is additive | ||
| on `main`. Map it from lite's `AUTH_ERROR { Expired }` and moq-transport's | ||
| `EXPIRED_AUTH_TOKEN`, and back again when refusing. | ||
| - Carry it through moq-ffi's error mapping and each wrapper. | ||
|
|
||
| ## Required | ||
|
|
||
| - [In-band auth](/quest/m1/auth/README.md) - the AUTH streams that carry these codes |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # [XS] OBS channel layouts | ||
|
|
||
| ## Goal | ||
|
|
||
| The OBS source maps a channel count to the same default layout moq-audio does, | ||
| the WAVE convention (3 is 2.1, 4 is quad, 6 is 5.1, 8 is 7.1), so a | ||
| multichannel broadcast plays with its speakers where the publisher put them. | ||
|
|
||
| ## Plan | ||
|
|
||
| `audio_layout_to_speakers` in `cpp/obs/src/moq-source.cpp` maps from FFmpeg | ||
| layouts today. Map each count to the nearest OBS `speaker_layout` and refuse | ||
| the ones OBS cannot place rather than guess. Note the mapping in `doc/bin/obs.md`. | ||
|
|
||
| ## Related | ||
|
|
||
| - [Audio codecs](/quest/m1/audio-codecs/README.md) - the channel layouts this mirrors | ||
|
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Make the layout quest a prerequisite rather than merely related. At this commit Useful? React with 馃憤聽/ 馃憥. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These quests are immediately ready even though their assumed foundation does not exist: a repo-wide search finds no
moq_archive::Reader, no Archive CLI source/sink, and nomoq-archivedependency inmoq-cli; those capabilities belong to the reader/writer siblings. Quest-list order is priority only, so withoutRequirededgesquest readycan dispatch paced replay or provenance first, forcing either an out-of-scope implementation of the archive stack or a blocked quest. Add the reader/writer dependencies, and make provenance depend on whichever quest owns the archive CLI modes.Useful? React with 馃憤聽/ 馃憥.