- Use ImportBatchStatus type instead of raw string literals in sweep job - Add a COUNT pre-check so the sweep UPDATE is skipped when no stale batches exist (avoids an unconditional write every minute) - Remove comment in disconnect route that explained what the code does Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import type { JobDefinition } from "@trails-cool/jobs";
|
|
import { and, lt, inArray, count } from "drizzle-orm";
|
|
import { getDb } from "../lib/db.ts";
|
|
import { importBatches, type ImportBatchStatus } from "@trails-cool/db/schema/journal";
|
|
import { logger } from "../lib/logger.server.ts";
|
|
|
|
const STALE_MS = 10 * 60 * 1000;
|
|
const STALE_STATUSES: ImportBatchStatus[] = ["pending", "running"];
|
|
|
|
export const importBatchesSweepJob: JobDefinition = {
|
|
name: "import-batches-sweep",
|
|
cron: "* * * * *",
|
|
retryLimit: 0,
|
|
expireInSeconds: 55,
|
|
async handler() {
|
|
const db = getDb();
|
|
const cutoff = new Date(Date.now() - STALE_MS);
|
|
const staleFilter = and(
|
|
inArray(importBatches.status, STALE_STATUSES),
|
|
lt(importBatches.startedAt, cutoff),
|
|
);
|
|
|
|
// Skip the write when nothing is stale to avoid an unconditional UPDATE every minute.
|
|
const rows = await db
|
|
.select({ staleCount: count() })
|
|
.from(importBatches)
|
|
.where(staleFilter);
|
|
if ((rows[0]?.staleCount ?? 0) === 0) return;
|
|
|
|
const result = await db
|
|
.update(importBatches)
|
|
.set({
|
|
status: "failed" satisfies ImportBatchStatus,
|
|
errorMessage: "Import timed out — the server may have restarted mid-import. Click 'Run again' to retry.",
|
|
completedAt: new Date(),
|
|
})
|
|
.where(staleFilter)
|
|
.returning({ id: importBatches.id });
|
|
|
|
logger.info({ count: result.length }, "import-batches-sweep: marked stale batches as failed");
|
|
},
|
|
};
|