fifteen/apps/web/lib/queue.ts

104 lines
3.5 KiB
TypeScript

import { Queue, QueueEvents } from "bullmq";
import { createBullMQConnection } from "./redis";
// Re-export shared job types so web code can import from one place
export type {
PipelineJobData,
DownloadPbfJobData,
ExtractPoisJobData,
GenerateGridJobData,
ComputeScoresJobData,
BuildValhallaJobData,
RefreshCityJobData,
JobProgress,
} from "@transportationer/shared";
export { JOB_OPTIONS } from "@transportationer/shared";
import type { PipelineJobData } from "@transportationer/shared";
// ─── Queue singleton ──────────────────────────────────────────────────────────
declare global {
// eslint-disable-next-line no-var
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var __pipelineQueue: Queue<any> | undefined;
// eslint-disable-next-line no-var
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var __downloadQueue: Queue<any> | undefined;
// eslint-disable-next-line no-var
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var __valhallaQueue: Queue<any> | undefined;
// eslint-disable-next-line no-var
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var __valhallaTransitQueue: Queue<any> | undefined;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getPipelineQueue(): Queue<any> {
if (!globalThis.__pipelineQueue) {
globalThis.__pipelineQueue = new Queue("pipeline", {
connection: createBullMQConnection(),
defaultJobOptions: {
attempts: 1,
removeOnComplete: { age: 86400 * 7 },
removeOnFail: { age: 86400 * 30 },
},
});
}
return globalThis.__pipelineQueue;
}
/** Queue for download-pbf jobs — concurrency 1 in the worker prevents parallel downloads. */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getDownloadQueue(): Queue<any> {
if (!globalThis.__downloadQueue) {
globalThis.__downloadQueue = new Queue("download", {
connection: createBullMQConnection(),
defaultJobOptions: {
attempts: 2,
removeOnComplete: { age: 86400 * 7 },
removeOnFail: { age: 86400 * 30 },
},
});
}
return globalThis.__downloadQueue;
}
/** Queue for build-valhalla jobs, processed by the valhalla-worker container. */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getValhallaQueue(): Queue<any> {
if (!globalThis.__valhallaQueue) {
globalThis.__valhallaQueue = new Queue("valhalla", {
connection: createBullMQConnection(),
defaultJobOptions: {
attempts: 1,
removeOnComplete: { age: 86400 * 7 },
removeOnFail: { age: 86400 * 30 },
},
});
}
return globalThis.__valhallaQueue;
}
/** Queue for build-valhalla transit jobs, processed by the valhalla-transit container. */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getValhallaTransitQueue(): Queue<any> {
if (!globalThis.__valhallaTransitQueue) {
globalThis.__valhallaTransitQueue = new Queue("valhalla-transit", {
connection: createBullMQConnection(),
defaultJobOptions: {
attempts: 1,
removeOnComplete: { age: 86400 * 7 },
removeOnFail: { age: 86400 * 30 },
},
});
}
return globalThis.__valhallaTransitQueue;
}
export function createQueueEvents(): QueueEvents {
return new QueueEvents("pipeline", {
connection: createBullMQConnection(),
});
}