Repository navigation
fix(net)!: the application owns a replacement track's start sequence - #5068
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…quences createTrack answers a request still queued for its name, and createTrack and insertTrack continue the name's group and datagram sequences within the broadcast, as Rust's create_track does. A broadcast remembers written sequences for up to 1024 names; unwritten, unheld names are swept and a new name past the bound is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Quest run outcome: implemented and
(Written by Claude Opus 5.5) |
…eover Keep this branch's track-name behavior in the JS net doc and main's timestamp wording. The broadcast tests import both the sequence bound and textFrame, and write frames with textFrame. Co-Authored-By: Grok 4.7 <noreply@x.ai>
createTrack is the only way to add a track by hand. It still answers a queued request, continues the name's sequences, and refuses a new name past 1024 with a plain Error. A request a handler already pulled stays duplicate. Co-Authored-By: Grok 4.7 <noreply@x.ai>
…eover # Conflicts: # quest/m0/js-track-takeover.md # quest/m1/README.md
An append on a producer that replaces an ended one under the same name no longer silently continues the name's sequences. It refuses (Rust Error::Duplicate, JS "duplicate sequence") when it would reuse a sequence the name already wrote; the application starts the replacement with an explicit create_group/writeGroup. Explicit writes stay unchecked so relays keep forwarding upstream numbering. @moq/publish now keeps each track for its network broadcast's life, so a re-announce or rendition change continues the same producer, and a maxAge change publishes a new network broadcast. Absorbs the publish catalog restart quest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 611c590637
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A rendition named like a catalog track would otherwise reuse the catalog's producer instead of failing as a duplicate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8b2a07ae3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Invalid info left the request's producer open, so a queued request answered by createTrack stranded its subscribers and held the name. Also document that Rendition.close leaves the network track with the broadcast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62f0672298
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A rendition track closed by an encoder error is recreated on re-register instead of reused, and registering a name under a different kind throws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f46a96dbe6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 054b563c32
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ew broadcast @moq/net no longer refuses a broadcast's 1025th track name. Like Rust, it sweeps names that never wrote and no producer holds as the record grows. @moq/publish moves to a new network broadcast when a closed rendition track must be replaced, since a replacement under the same name would restart its sequences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review (Written by Claude Opus 5.5) |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
# Conflicts: # doc/lib/js/net.md # js/net/src/track.ts # quest/m0/broadcast-epoch/README.md # rs/moq-net/src/model/broadcast.rs
|
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 15 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. Comment |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: bea1e2e
No actionable bugs found in the full PR diff and surrounding sequence, request, catalog, and encoder-lifetime code. The direction is coherent: applications choose replacement sequences, explicit forwarding remains available, and publish keeps tracks for the network broadcast's lifetime. Restarting the broadcast for retention changes or failed-track replacements avoids a second application-side sequence ledger.
The earlier findings about queued-request validation, catalog-name collisions, rendition-kind lifetime, and failed-track replacement appear addressed in the current code; I found no independent remaining instance to flag.
Verification limits: GitHub-only static review of implementation and regression tests. I did not run tests, builds, or browser/media playback, and this is not a test-pass claim.
(Written by OpenAI)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bea1e2e054
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review (Written by Claude Opus 5.5) |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Merge summary for
(Written by Claude Opus 5.5) |
Problem
A track name always means the same content, so a producer that replaces an ended one under the same name must never reuse its group or datagram sequences. #4929 handled that in the library: Rust's producers, and JS's on-demand producers, silently continued from wherever the name's last producer stopped. JS
createTrackdidn't, so@moq/publishrestarted its catalog at group 0 on every re-announce. It also restarted every rendition track whenever a rendition was registered or removed.Direction from the maintainer: the application owns the start sequence. The library should not quietly start somewhere else. It should fail loudly when an app reuses a name in a way that would repeat sequences.
Approach
Error::Duplicatein Rust,Error("duplicate sequence: ...")in JS. A replacement picks its start by writing its first group with an explicit sequence (create_group/writeGroup), and later appends continue from there. Explicit writes stay unchecked, so a relay can still forward upstream sequences, including a group it had before. A new broadcast starts over.createTrackanswers a queued request, as Rust'screate_trackdoes. This is separate from sequences: without it, subscribers queued for a name stay stuck once the app creates the track.insertTrackis removed. It has no Rust counterpart and no production caller. It would also bypass the name's sequence record.@moq/publishowns its sequences. Each track, catalog included, lives as long as the network broadcast. A re-announce, a rendition change, or re-registering a name keeps writing to the same producer. AmaxAgechange publishes a new network broadcast, because a track's retention is fixed when it is created. A rendition name keeps its kind within one network broadcast. A rendition track that closed (an encoder error) can't be continued, so replacing it publishes a new network broadcast, where the name starts over. This absorbs publish catalog restart, which is deleted.Request.acceptrejects on any failure, invalid info included, so a request is never left open with subscribers waiting.Decisions
Settled 2026-10-09, still holding:
A new name past the bound is a plainSuperseded by 8.Error("too many track names").The bound is 1024 names per broadcast.Superseded by 8.insertTrackis removed in this PR, not in a separate quest (confirmed 2026-10-11). ✅duplicate, as in Rust. ✅Settled 2026-10-11 (maintainer direction: the application owns the start sequence):
@moq/publishcomplies. Options: (a) keep each track for the network broadcast's life, and move to a new broadcast onmaxAge✅; (b) mint a fresh broadcast on every re-announce or rendition change; (c) carry sequences by hand into re-created tracks.Settled 2026-10-11 by the maintainer:
@moq/publishmove to a new network broadcast, since a new broadcast is new content, in this PR ✅; (c) carry the closed track's next sequence into the replacement.Impact
moq-net): no signature change. Behavior change:track::Producer::append_groupandappend_datagramreturnError::Duplicateinstead of continuing past an earlier producer of the same name. This applies tocreate_track,reserve_track, and on-demand requests.@moq/net): breaking.BroadcastProducer.insertTrackis removed.Track.Producer.appendGroup/appendDatagramthrowduplicate sequenceinstead of continuing past an earlier producer of the name.createTrackanswers a queued request instead of throwingduplicate track.@moq/publish: tracks persist for the network broadcast's life.Rendition.close()no longer closes the network track. AmaxAgechange, or replacing a closed rendition track, recreatesbroadcast.net. Registering a name under a different kind on the same network broadcast throws.@moq/netbehavior:Request.acceptcloses the request's producer with the error whenever it throws.test/interop/clients/rust/tail.rs: formatting only. chore(interop): rustfmt the rust tail client #5377 reindented it with tabs, but no rustfmt config coverstest/interop, socargo fmt --all --checkfailed for any Rust change. Restored to its pre-chore(interop): rustfmt the rust tail client #5377 form.Testing
replacement_refuses_reused_sequences,stale_producer, androute_change.rsproducer_replaced_*(an app replacing an aborted producer continues explicitly).createTrackwith invalid info rejects the queued request it answers.maxAgechange swaps the network broadcast. The re-announce, rendition-change, and closed-track tests fail without the fix.just check. There is no wire change, so the interop suite is not affected.Follow-ups
@moq/publishdoes not recover a rendition track that closes mid-stream until the rendition set changes, as onmain. Restarting reactively on close would loop on a dead audio encoder, which closes every track it is handed, so recovery needs to decide which closes are recoverable.test/interop/clients/rusta rustfmt config (or movers/.rustfmt.tomlto the root) so its formatting no longer depends on the environment.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code