feat: whisper-side cancellation + SSE-triggered retry
All checks were successful
Build & Push Docker Image / build-and-push (push) Successful in 48s

- Add cancelJob() to whisper.ts: sends DELETE /jobs/:id to the whisper
  server (best-effort, errors silently ignored)
- DELETE /api/jobs/[id] now calls cancelJob() when cancelling an active
  job that has a whisperJobId, stopping GPU use immediately
- Webhook handler guards against locally-cancelled jobs: returns ok early
  so whisper's late completion cannot overwrite cancelled status or send
  a phantom 'Transcript ready' notification
- Replace blind sleep(Retry-After + 1s) in submitJob() with
  waitForModelReady(): subscribes to /model/events SSE and proceeds as
  soon as state:ready arrives; falls back to the Retry-After timeout if
  SSE is unreachable or closes without model_ready
- Refactor retry tests to use URL-aware makeJobFetch() helper; add 7 new
  tests (3 SSE-triggered retry, 3 cancelJob, 1 webhook cancelled-guard)
  — 144/144 passing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Giancarmine Salucci
2026-05-09 00:40:40 +02:00
parent 01845bec25
commit 04142b17a8
5 changed files with 267 additions and 73 deletions

View File

@@ -12,6 +12,11 @@ const jobId = params.jobId;
const job = getJob(jobId);
if (!job) throw error(404, 'Job not found');
// Discard the result if the job was cancelled locally while whisper was running
if (job.status === 'cancelled') {
return json({ ok: true });
}
const whisperJob = (await request.json()) as WhisperJob;
if (whisperJob.status === 'failed' || whisperJob.status === 'cancelled') {