haixunMaster/lib/jobs/cancel.ts

55 lines
1.5 KiB
TypeScript

import { prisma } from "@/lib/db";
const cancelledIds = new Set<string>();
export class JobCancelledError extends Error {
constructor(message = "任務已停止") {
super(message);
this.name = "JobCancelledError";
}
}
export function markJobCancelledLocal(jobId: string) {
cancelledIds.add(jobId);
}
export function clearJobCancelledLocal(jobId: string) {
cancelledIds.delete(jobId);
}
export async function isJobCancelled(jobId: string): Promise<boolean> {
if (cancelledIds.has(jobId)) return true;
const job = await prisma.backgroundJob.findUnique({
where: { id: jobId },
select: { status: true },
});
return job?.status === "cancelled";
}
export async function assertJobNotCancelled(jobId?: string) {
if (!jobId) return;
if (await isJobCancelled(jobId)) {
throw new JobCancelledError();
}
}
export async function cancelJob(jobId: string): Promise<{ ok: boolean; error?: string }> {
const job = await prisma.backgroundJob.findUnique({ where: { id: jobId } });
if (!job) return { ok: false, error: "找不到任務" };
if (job.status === "completed") return { ok: false, error: "任務已完成" };
if (job.status === "failed") return { ok: false, error: "任務已失敗" };
if (job.status === "cancelled") return { ok: true };
markJobCancelledLocal(jobId);
await prisma.backgroundJob.update({
where: { id: jobId },
data: {
status: "cancelled",
progress: "已停止",
completedAt: new Date(),
},
});
return { ok: true };
}