Skip to content

fix: cancel yt-dlp audio imports reliably when no child process is running - #6092

Merged
atomantic merged 2 commits into
mainfrom
claim/issue-6013
Sep 3, 2026
Merged

fix: cancel yt-dlp audio imports reliably when no child process is running#6092
atomantic merged 2 commits into
mainfrom
claim/issue-6013

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

cancelYoutubeImport / cancelReferenceAudioImport decided whether a cancel was possible by looking at job.process. That field is transient — it is null while the job is being set up and again during post-processing, because runYtDlp clears it the moment the child exits. A cancel landing in either window returned false, emitted no { type: 'canceled' } frame, and let the import go on to land the audio file and create the Track / uploads record anyway.

  • Both jobs now carry a canceled flag; cancel* sets it and only signals killWithEscalation when a child is actually running.
  • The kickoff re-checks the flag at each phase boundary (before the download, and again before the file landing / record creation), emitting { type: 'canceled' } and cleaning temp files instead of committing the import.
  • The core's canceled outcome and the flag are handled by one shared abort path rather than two branches.
  • Cancelling a job that already finished still reports false: the job lingers in the map until closeJobAfterDelay evicts it, so the kickoff marks it done and cancel* requires a running status.
  • Both modules export __testing = { importJobs }, matching videoDownload.js, so the cancel path is unit-testable at all.

Test plan

  • server/services/trackYoutubeImport.test.js and server/services/roundReferenceAudioImport.test.js gain cancellation coverage: unknown job id, cancel with no child spawned yet, cancel signalling a running child plus a rejected second cancel, cancel of a finished-but-not-yet-evicted job, and a kickoff cancelled after the download finished (asserts canceled is broadcast and importUploadedTrack / createTrack / importFileToUploads are never called).
  • Verified the new tests fail against the pre-fix sources (6 failures) and pass after.
  • cd server && npx vitest run services/trackYoutubeImport.test.js services/roundReferenceAudioImport.test.js services/ytdlpAudioImport.test.js services/videoDownload.test.js routes/tracks.test.js routes/rounds.test.js — all green.

Closes #6013

… null job.process (#6013)

cancelYoutubeImport/cancelReferenceAudioImport keyed off job.process, which is
null both during job setup and again during post-processing (runYtDlp clears it
on child exit). A cancel in either window returned false, emitted no canceled
frame, and let the import commit a track/upload anyway. Both jobs now carry a
canceled flag that the kickoff re-checks at each phase boundary, and both
modules export __testing so the cancel path is actually unit-tested.
…ed (#6013)

Review follow-up: the job lingers in the map until closeJobAfterDelay evicts
it, so guarding cancel on the canceled flag alone made a cancel for a completed
import answer ok:true. Mark the job done in the kickoff's finally and require a
running status.
@atomantic
atomantic merged commit df6d66d into main Sep 3, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-6013 branch September 3, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

trackYoutubeImport and roundReferenceAudioImport ignore cancellation before spawn and during post-processing, with missing test coverage

1 participant