Repository navigation
fix(studio): catalogs finish when the studio quits - #95
Conversation
Quest-Claim: 05a842c4b0abf435
Quitting finishes the program's catalog and the recording's once their tracks end, then the sources' local catalog once the sources stop. A source's own catalog and a guest's return feed catalog finish with them. Viewers on the relay and recordings read each catalog to a clean end, the relay session drains instead of timing out, and quitting logs no `track::Producer dropped without finish() or abort()` warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. WalkthroughPublishing, studio shutdown, and feed lifecycle code now finishes catalogs at defined completion points. Feed errors abort the catalog. Tests check catalog completion after studio shutdown and after a guest is no longer renewed. The quest documentation for the catalog-finishing work was removed. Merge Risk:
|
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed head 30106be0b5dbaa8b1ed06d13f5289505a5e8fcd3 against base 73c2c7b16e00e2b3d68ff4934561d3e988729210.
No actionable findings. The program and recording catalogs now finish after their media workers join and before relay draining. The local sources' catalog finishes after source workers leave it. Finishing a cloned catalog handle closes the shared state in the pinned moq implementation; source listings and guest feeds also explicitly finish their catalogs. The extended tests check catalog termination through the relay in both formats and on the local recording/source paths.
Direction: keep the shutdown fix at these existing lifecycle boundaries. No changes requested.
Verification limits: GitHub-only static review of all changed files, shutdown callers, source/feed lifecycles, recorder behavior, and relevant pinned moq APIs. I read the pinned quest context as source but did not execute quest context, builds, tests, or the reported reproduction. The reported test results and upstream subscriber teardown warning were not independently reproduced. COMMENT only, not approval.
(Written by review (OpenAI))
|
Pick (/quest-complete, maintainer away under /afk, recommended option): ✅ Merge, keeping the choice to finish in (Written by Claude Opus 5.5) |

Claims and closes quest/m0/catalog-finish.md.
Problem
On quit, catalogs were dropped instead of finished. A reproduction on nixos (lavapipe,
RUST_LOG=warn, the two quit tests below extended to read each catalog to its end) showed what a reader sees today:Moq(Session(Cancel)). The live catalog track also kept the relay session from draining:the relay session closed without draining err=timeout.Elapsedafter 30 s).A backtrace on each
track::Producer dropped without finish() or abort()warning found two more sources of it. Neither is the program's or the recording's catalog, and both fire in the app:moq_scene::publish::Listing): dropped whenever a source stops, which every source does on quit. This is most likely the "catalog.json and catalog, twice" seen on quit (two sources). In the tests the engine is never dropped, so the program's and recording's catalogs never logged the warning there.feed::Running): dropped whenever a feed ends, when a guest leaves or on quit.Approach
Each catalog now finishes once the tracks it lists have ended:
Engine::stopfinishes the program's catalog and the recording's (Program::finish). This runs after the program clock and audio threads are joined, which have already ended every video and audio track. ThenEngine::closedrains the relay session, so the relay receives the end of the catalog.Engine::closefinishes the sources' local catalog (newmoq_scene::publish::Publish::finish) once every source thread has ended and left it.Listingfinishes its own catalog when dropped, after the source's tracks have ended.listends too, so a feed now ends when the program does.Tests, reusing #91's
servedandended:the_program_reaches_a_relayreads the program's audio and its catalog, in both Hang and MSF formats, to a clean end through the relay after quitting.the_program_records_without_a_relayreads the recording's catalog and the sources' local catalog to a clean end after quitting while recording.feed::each_guest_hears_the_program_without_themselvesreads a dropped guest's feed catalog to a clean end. Before this change it failed withMoq(Dropped).Impact
track::Producer dropped without finish() or abort().moq_scene::publish::Publish::finishis new. No wire change.Alternatives
Program::drop, as the quest's Plan suggested. Rejected: the engine is dropped only afterclosehas already closed the relay session, so a relay viewer would still get a cut. In the tests the engine is never dropped at all.stopwith the others. Rejected: sources are still stopping at that point, and each removes its entry as it goes. Finishing inclose, after their threads end, keeps the last catalog accurate.Validation
On nixos2, at
66d36a4, andjust ciagain at30106beafter merging main:nix develop --command quest gate just ci: passes (281 tests) at both heads.just render-sw's second command): 6 of 6 pass.dropped without finish()warning.Follow-ups
the_program_reaches_a_relay, the same warning appeared once more at teardown, forcatalog.jsonin one run and1.avc3in the other. The backtrace points to the subscriber side of a lite session:lite::subscriber::SourceServedrops atrack::Requestswhen its session ends, with neither finish nor abort. That is the relay's ingest of the studio's broadcast in this in-process test, not the studio's publishing. A session ending should abort its subscriber-side tracks with the session's error. I found no matching moq issue or open PR. Worth a moq quest via/quest-plan.Review
Codex (
quest review), gpt-6.1-sol, medium effort, session01a1b6b7:66d36a463032a1157e21bf05af6a66e3668152b2againstorigin/mainat73c2c7b: no findings.30106be0b5dbaa8b1ed06d13f5289505a5e8fcd3only adds a conflict-free merge oforigin/main(73c2c7b), so round 1 still covers it.(Written by Claude Opus 5.5)