import { PgBoss } from "pg-boss"; import { logger } from "@/lib/logger"; /** * Die Auftragswarteschlange (pg-boss auf derselben PostgreSQL, Schema `pgboss`). Die app stellt * nur ein, der worker arbeitet ab. Ein Auftrag wird nie automatisch wiederholt: halb angelegte * Gäste soll ein Mensch ansehen, nicht eine Schleife. */ export const WARTESCHLANGE = "auftrag"; /** Template-Bau kann bei langsamem Download dauern; danach gilt ein Job als verwaist. */ const LAUFZEIT_SEKUNDEN = 4 * 3600; export type AuftragsJob = { auftragId: string }; let instanz: Promise | undefined; export function boss(rolle: "app" | "worker"): Promise { instanz ??= (async () => { const url = process.env["DATABASE_URL"]; if (!url) throw new Error("DATABASE_URL ist nicht gesetzt."); const b = new PgBoss({ connectionString: url, application_name: `proxdeploy-${rolle}`, // Wartung und Zeitpläne macht nur der worker; die app stellt nur ein. supervise: rolle === "worker", schedule: false, }); b.on("error", (fehler) => logger.error({ err: fehler }, "pg-boss")); await b.start(); await b.createQueue(WARTESCHLANGE, { retryLimit: 0, expireInSeconds: LAUFZEIT_SEKUNDEN }); return b; })(); return instanz; } export async function auftragEinstellen(auftragId: string): Promise { const b = await boss("app"); await b.send(WARTESCHLANGE, { auftragId } satisfies AuftragsJob, { retryLimit: 0, expireInSeconds: LAUFZEIT_SEKUNDEN, }); }