175 lines
5 KiB
TypeScript
175 lines
5 KiB
TypeScript
import type { RoutingMode } from "./osm-tags.js";
|
|
|
|
// ─── Job data types ───────────────────────────────────────────────────────────
|
|
|
|
export interface DownloadPbfJobData {
|
|
type: "download-pbf";
|
|
citySlug: string;
|
|
geofabrikUrl: string;
|
|
expectedBytes?: number;
|
|
}
|
|
|
|
export interface ExtractPoisJobData {
|
|
type: "extract-pois";
|
|
citySlug: string;
|
|
pbfPath: string;
|
|
/** Optional bounding box [minLng, minLat, maxLng, maxLat] to clip PBF before tag-filtering */
|
|
bbox?: [number, number, number, number];
|
|
}
|
|
|
|
export interface GenerateGridJobData {
|
|
type: "generate-grid";
|
|
citySlug: string;
|
|
resolutionM: number;
|
|
}
|
|
|
|
export interface ComputeScoresJobData {
|
|
type: "compute-scores";
|
|
citySlug: string;
|
|
modes: RoutingMode[];
|
|
thresholds: number[];
|
|
/** Set after compute-routing children are dispatched (internal two-phase state). */
|
|
routingDispatched?: boolean;
|
|
/** When true, ingest-boris-ni is dispatched in Phase 1 to run alongside routing jobs. */
|
|
ingestBorisNi?: boolean;
|
|
/** When true, ingest-boris-hb is dispatched in Phase 1 to run alongside routing jobs. */
|
|
ingestBorisHb?: boolean;
|
|
}
|
|
|
|
export interface ComputeRoutingJobData {
|
|
type: "compute-routing";
|
|
citySlug: string;
|
|
mode: "walking" | "cycling" | "driving";
|
|
category: string;
|
|
}
|
|
|
|
export interface ComputeTransitJobData {
|
|
type: "compute-transit";
|
|
citySlug: string;
|
|
}
|
|
|
|
export interface BuildValhallaJobData {
|
|
type: "build-valhalla";
|
|
/** City being added/updated. Absent for removal-only rebuilds. */
|
|
citySlug?: string;
|
|
pbfPath?: string;
|
|
/** Optional bounding box [minLng, minLat, maxLng, maxLat] to clip PBF before building routing tiles */
|
|
bbox?: [number, number, number, number];
|
|
/** Slugs to drop from the global routing tile set before rebuilding */
|
|
removeSlugs?: string[];
|
|
}
|
|
|
|
export interface RefreshCityJobData {
|
|
type: "refresh-city";
|
|
citySlug: string;
|
|
geofabrikUrl: string;
|
|
resolutionM?: number;
|
|
/** Monotonically increasing counter incremented at each trigger; used in jobIds
|
|
* to prevent completed-job deduplication on re-runs. */
|
|
iter: number;
|
|
/** ID of the compute-scores job enqueued for this refresh; set after flow.add(). */
|
|
computeScoresJobId?: string;
|
|
}
|
|
|
|
export interface IngestBorisNiJobData {
|
|
type: "ingest-boris-ni";
|
|
citySlug: string;
|
|
}
|
|
|
|
export interface IngestBorisHbJobData {
|
|
type: "ingest-boris-hb";
|
|
citySlug: string;
|
|
}
|
|
|
|
export interface DownloadGtfsDeJobData {
|
|
type: "download-gtfs-de";
|
|
url: string;
|
|
/** Re-download even if data already exists */
|
|
force?: boolean;
|
|
/**
|
|
* Per-city bounding boxes [minLng, minLat, maxLng, maxLat] used to clip the
|
|
* GTFS feed after extraction. A stop is kept when it falls inside ANY of the
|
|
* bboxes (each already padded by a small buffer in refresh-city.ts).
|
|
* When absent the full feed is kept.
|
|
*/
|
|
bboxes?: [number, number, number, number][];
|
|
}
|
|
|
|
export type PipelineJobData =
|
|
| DownloadPbfJobData
|
|
| ExtractPoisJobData
|
|
| GenerateGridJobData
|
|
| ComputeScoresJobData
|
|
| ComputeRoutingJobData
|
|
| BuildValhallaJobData
|
|
| RefreshCityJobData
|
|
| IngestBorisNiJobData
|
|
| IngestBorisHbJobData
|
|
| DownloadGtfsDeJobData
|
|
| ComputeTransitJobData;
|
|
|
|
// ─── Job options (BullMQ-compatible plain objects) ────────────────────────────
|
|
|
|
export const JOB_OPTIONS: Record<PipelineJobData["type"], object> = {
|
|
"compute-transit": {
|
|
attempts: 1,
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"download-gtfs-de": {
|
|
attempts: 2,
|
|
backoff: { type: "fixed", delay: 10000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"compute-routing": {
|
|
attempts: 2,
|
|
backoff: { type: "fixed", delay: 3000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"download-pbf": {
|
|
attempts: 2,
|
|
backoff: { type: "fixed", delay: 5000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"extract-pois": {
|
|
attempts: 1,
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"generate-grid": {
|
|
attempts: 1,
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"compute-scores": {
|
|
attempts: 1,
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"build-valhalla": {
|
|
attempts: 3,
|
|
backoff: { type: "fixed", delay: 60_000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"refresh-city": {
|
|
attempts: 1,
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"ingest-boris-ni": {
|
|
attempts: 2,
|
|
backoff: { type: "fixed", delay: 5000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
"ingest-boris-hb": {
|
|
attempts: 2,
|
|
backoff: { type: "fixed", delay: 5000 },
|
|
removeOnComplete: { age: 86400 * 7 },
|
|
removeOnFail: { age: 86400 * 30 },
|
|
},
|
|
};
|