stop button aborts queue loop, remaining jobs stay pending in queue
Build and Push Docker Image / build (push) Successful in 6m48s
Build and Push Docker Image / build (push) Successful in 6m48s
previously stop only killed the running ffmpeg process — the loop immediately picked up the next pending job. now the abort signal breaks the loop between jobs, so remaining items stay in the queue column as pending jobs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-3
@@ -21,6 +21,7 @@ const app = new Hono();
|
||||
// ─── Sequential local queue ──────────────────────────────────────────────────
|
||||
|
||||
let queueRunning = false;
|
||||
let queueAbort: AbortController | null = null;
|
||||
let runningProc: ReturnType<typeof Bun.spawn> | null = null;
|
||||
let runningJobId: number | null = null;
|
||||
let activeQueue: Job[] | null = null;
|
||||
@@ -65,6 +66,8 @@ function emitQueueStatus(
|
||||
async function runSequential(initial: Job[]): Promise<void> {
|
||||
if (queueRunning) return;
|
||||
queueRunning = true;
|
||||
queueAbort = new AbortController();
|
||||
const { signal } = queueAbort;
|
||||
try {
|
||||
let first = true;
|
||||
const queue: Job[] = [...initial];
|
||||
@@ -73,6 +76,7 @@ async function runSequential(initial: Job[]): Promise<void> {
|
||||
activeSeen = seen;
|
||||
|
||||
while (queue.length > 0) {
|
||||
if (signal.aborted) break;
|
||||
const job = queue.shift() as Job;
|
||||
|
||||
// Pause outside the processing window
|
||||
@@ -111,8 +115,8 @@ async function runSequential(initial: Job[]): Promise<void> {
|
||||
|
||||
// When the local queue drains, re-check the DB for jobs that were
|
||||
// approved mid-run. Without this they'd sit pending until the user
|
||||
// manually clicks "Run all" again.
|
||||
if (queue.length === 0) {
|
||||
// manually clicks "Run all" again. Skip if aborted — user wants to stop.
|
||||
if (queue.length === 0 && !signal.aborted) {
|
||||
const more = db.prepare("SELECT * FROM jobs WHERE status = 'pending' ORDER BY created_at").all() as Job[];
|
||||
enqueueUnseenJobs(queue, seen, more);
|
||||
}
|
||||
@@ -121,6 +125,7 @@ async function runSequential(initial: Job[]): Promise<void> {
|
||||
activeQueue = null;
|
||||
activeSeen = null;
|
||||
queueRunning = false;
|
||||
queueAbort = null;
|
||||
emitQueueStatus("idle");
|
||||
}
|
||||
}
|
||||
@@ -300,8 +305,12 @@ app.post("/clear-completed", (c) => {
|
||||
// ─── Stop running job ─────────────────────────────────────────────────────────
|
||||
|
||||
app.post("/stop", (c) => {
|
||||
// Abort the queue loop so no more jobs start after the current one
|
||||
if (queueAbort) queueAbort.abort();
|
||||
|
||||
if (!runningProc || runningJobId == null) {
|
||||
return c.json({ ok: false, error: "No job is currently running" }, 409);
|
||||
// No active ffmpeg but queue loop might be between jobs — abort is enough
|
||||
return c.json({ ok: true, stopped: null });
|
||||
}
|
||||
const stoppedId = runningJobId;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user