You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Serialize mux, upload, cancellation, and eviction across an export session #18
Audited main at a7bad12. Existing tests pass: 33 Python, 9 JavaScript.
The append_lock protects video appends only. mux_session does not wait for active video/audio uploads, and treats an existing audio.bin as complete. Cancellation and session eviction can also remove a working directory during an operation. Multiple mux requests can retain the same session before its eventual pop, notably while resolving host audio.
Reproduced with a video request yielding a 16 KiB chunk, then blocked before its final chunk. A concurrent mux request invoked the FFmpeg boundary and returned FileResponse while the upload was still active. Thus FFmpeg can read incomplete media and the session is consumed before the upload finishes; response cleanup can then remove its files. This reproducer used a stubbed FFmpeg boundary to observe invocation deterministically.
Introduce a session lifecycle lock/state shared by uploads, mux, cancel, and eviction. Only mux finalized media, permit a single mux owner, and keep cleanup from removing files still in use. Add barrier-based tests for upload-versus-mux, duplicate mux, and cancellation/eviction during active operations.
routes.py now serializes every operation that touches an export session's work dir behind a single per-session lifecycle lock (state["lock"], replacing the video-append-only append_lock): uploads hold it for their whole stream, mux holds it across audio resolution and the FFmpeg run (making it the single mux owner), and cancel/eviction take it before removing files. This closes the reproduced race where a mux invoked FFmpeg on a partial stream and consumed the session out from under an active upload, plus duplicate-mux races during host-audio resolution.
Added six barrier-based tests, each proven to fail against a mutated routes.py: upload-versus-mux for both video and audio, duplicate mux (one FFmpeg invocation, [200, 404]), cancel and eviction during an active upload, and cancellation mid-mux (work dir no longer leaked). Full suite: 43 passed. Bumped plugin.json to 0.3.3 and updated CHANGELOG/CLAUDE.md.
Activity
pullfrog commentedon Oct 11, 2026
pullfrog commentedon Oct 11, 2026
Built issue #18. PR: #20
routes.pynow serializes every operation that touches an export session's work dir behind a single per-session lifecycle lock (state["lock"], replacing the video-append-onlyappend_lock): uploads hold it for their whole stream, mux holds it across audio resolution and the FFmpeg run (making it the single mux owner), and cancel/eviction take it before removing files. This closes the reproduced race where a mux invoked FFmpeg on a partial stream and consumed the session out from under an active upload, plus duplicate-mux races during host-audio resolution.Added six barrier-based tests, each proven to fail against a mutated
routes.py: upload-versus-mux for both video and audio, duplicate mux (one FFmpeg invocation,[200, 404]), cancel and eviction during an active upload, and cancellation mid-mux (work dir no longer leaked). Full suite: 43 passed. Bumpedplugin.jsonto 0.3.3 and updated CHANGELOG/CLAUDE.md.Task list (7/7 completed)
big-pickle(free) | 𝕏