feat(admin): say what a queued restore is waiting for

A restore never runs beside a backup pass or another large job: the
heavy lane puts its delivery back in the queue for a minute at a time.
The job's own row says queued for the whole wait, and the console said
the restore starts "as soon as the background worker picks it up",
which read as a stuck worker while a backup ran.

The status routes now ask the queue. A delivery the lane put back sits
in created with a start_after ahead of now, and the active row of a
heavy queue is what holds the lane. The job view carries
waiting: "backup" | "busy" | null, and the console says it waits for
the running backup, or for another large job, and since when it has
been queued, in all nine locales. A queue that cannot be asked answers
no wait and is reported at warn.

The job view and its reads move to backup-restore-view.ts, which keeps
the worker module under its size baseline.
This commit is contained in:
Marc-André Bombeck committed 2026-10-23 21:43:55 +02:00
1 parent 6a87810dbf
commit 7936ab9a57
28 files changed
+544 -199

No files matched your search

@@ -7,10 +7,8 @@
*/
import { apiHandler, HttpError, requireAdmin } from "@/lib/api-handler";
import { apiSuccess } from "@/lib/api-response";
import {
evictAfterRestore,
readBackupRestoreJob,
} from "@/lib/jobs/backup-restore";
import { evictAfterRestore } from "@/lib/jobs/backup-restore";
import { readBackupRestoreJob } from "@/lib/jobs/backup-restore-view";
import { annotate } from "@/lib/logging/context";
export const dynamic = "force-dynamic";
+2 -4
View File
@@ -8,10 +8,8 @@
*/
import { apiHandler, requireAdmin } from "@/lib/api-handler";
import { apiSuccess } from "@/lib/api-response";
import {
evictAfterRestore,
listRecentBackupRestoreJobs,
} from "@/lib/jobs/backup-restore";
import { evictAfterRestore } from "@/lib/jobs/backup-restore";
import { listRecentBackupRestoreJobs } from "@/lib/jobs/backup-restore-view";
import { annotate } from "@/lib/logging/context";
export const dynamic = "force-dynamic";