ravenflow 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/job/definition.ts","../src/job/any-job.ts","../src/job/continuation.ts","../src/job/deduplication-id.ts","../src/job/policies.ts","../src/config/validate-config/schemas/primitives.ts","../src/config/validate-config/schemas/pace.schema.ts","../src/spools/governor.ts","../src/config/validate-config/schemas/trigger.schema.ts","../src/config/validate-config/schemas/job.schema.ts","../src/config/constants.ts","../src/config/validate-config/schemas/config.schema.ts","../src/config/validate-config/shape-errors.ts","../src/config/validate-config/declared-jobs.ts","../src/config/validate-config/shared-spool-errors.ts","../src/config/validate-config/spool-pace-errors.ts","../src/config/validate-config/index.ts","../src/logger.ts","../src/mongo/connection.ts","../src/queues/declared-queues.ts","../src/queues/open-queues.ts","../src/queues/close-queues.ts","../src/queues/build-job-options.ts","../src/queues/link-id.ts","../src/control-plane/control-key.ts","../src/control-plane/cache/control-cache.ts","../src/control-plane/control-plane.ts","../src/control-plane/redis-connection.ts","../src/control-plane/channel/control-channel.ts","../src/control-plane/levers.ts","../src/control-plane/store/live-controls.ts","../src/control-plane/store/rehydrate-controls.ts","../src/control-plane/store/control-store.ts","../src/control-plane/store/control-hash.ts","../src/control-plane/store/control-mirror.ts","../src/control-plane/init-control-plane.ts","../src/spools/backlog.ts","../src/spools/spool-job-id.ts","../src/spools/item-runs.ts","../src/client/job-proxy/build-backlog.ts","../src/client/job-proxy/controls.ts","../src/client/job-proxy/deduplication.ts","../src/client/job-proxy/send.ts","../src/client/job-proxy/spool-ingest.ts","../src/client/job-proxy/init-job-proxies.ts","../src/client/ravenflow-client.ts","../src/client/create-ravenflow-client.ts","../src/describe-error.ts","../src/worker/banner.ts","../src/worker/control-plane-reader.ts","../src/worker/log-bullmq-errors.ts","../src/worker/mongodb-deadline-on-close.ts","../src/worker/job-results-recorder/batch-writer.ts","../src/worker/job-results-recorder/job-results-collection.ts","../src/worker/job-router/execution-gate.ts","../src/worker/job-router/pace-gate.ts","../src/worker/job-router/execution-signal.ts","../src/worker/job-router/job-logger.ts","../src/worker/job-router/link-deduplication.ts","../src/worker/job-router/next-link.ts","../src/worker/job-router/run-link.ts","../src/worker/job-router/progress-marks.ts","../src/worker/job-router/trigger-gate.ts","../src/worker/job-router/route-by-name.ts","../src/worker/job-results-recorder/job-result-limits.ts","../src/worker/job-results-recorder/error-extraction.ts","../src/worker/job-results-recorder/storable-value.ts","../src/worker/job-results-recorder/job-result.ts","../src/worker/job-results-recorder/log-capture.ts","../src/worker/job-results-recorder/job-results-listener.ts","../src/worker/job-results-recorder/job-results-recorder.ts","../src/worker/internal-jobs/job-results-aggregator/aggregated-results-collection.ts","../src/worker/internal-jobs/job-results-aggregator/aggregate-job-results.ts","../src/worker/internal-jobs/job-results-aggregator/job-results-aggregator.ts","../src/worker/internal-jobs/spool-feeder/feed-spool.ts","../src/worker/internal-jobs/spool-feeder/item-removals.ts","../src/worker/internal-jobs/spool-feeder/stage.ts","../src/worker/internal-jobs/spool-feeder/ticks.ts","../src/worker/internal-jobs/spool-feeder/spool-feeder.ts","../src/worker/open-worker.ts","../src/worker/schedulers.ts","../src/worker/served-queue.ts","../src/worker/serving.ts","../src/worker/withdrawal/mongo-watch.ts","../src/worker/withdrawal/withdraw.ts","../src/worker/ravenflow-worker.ts","../src/worker/create-ravenflow-worker.ts","../src/config/ravenflow-config.ts"],"names":["z","isObject","pino","MongoClient","Queue","Redis","stored","ObjectId","Job","isRedisInstance","release","MongoBulkWriteError","DelayedError","Worker","format","inspect","BSON","SECONDS_PER_HOUR","secondsOf","TICKS_KEPT","scheduleTicks","ONE_TICK_AT_A_TIME","MetricsTime"],"mappings":"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","file":"index.js","sourcesContent":["import type { Continuation } from \"./continuation\";\nimport type { JobContext } from \"./context\";\nimport type { BackoffPolicy, DeduplicatePolicy, PacePolicy } from \"./policies\";\nimport type { CronTrigger, SpoolTriggerDeclaration } from \"./trigger\";\nimport type { CronTriggerFor, TriggerFor } from \"./trigger-for\";\n\nexport interface JobDefinition<TPayload, TResult> {\n queue?: string;\n attempts?: number;\n backoff?: BackoffPolicy;\n trigger?: TriggerFor<TPayload>;\n deduplicate?: DeduplicatePolicy<TPayload>;\n pace?: PacePolicy;\n handler: JobHandler<TPayload, TResult>;\n}\n\nexport type JobHandler<TPayload, TResult> = (\n ctx: JobContext<TPayload>,\n) => Promise<TResult | Continuation<TPayload>>;\n\nexport type SpoolFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {\n trigger: SpoolTriggerDeclaration;\n pace: PacePolicy;\n};\n\nexport type ClockFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {\n trigger: CronTrigger;\n};\n\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinitionWith<SpoolTriggerDeclaration, TPayload, TResult> & { pace: PacePolicy },\n): SpoolFedJob<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinitionWith<CronTriggerFor<TPayload>, TPayload, TResult>,\n): ClockFedJob<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: UnspooledJobDefinition<TPayload, TResult>,\n): JobDefinition<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinition<TPayload, TResult>,\n): JobDefinition<TPayload, TResult> {\n return { ...definition };\n}\n\ntype JobDefinitionWith<TTrigger, TPayload, TResult> = Omit<\n JobDefinition<TPayload, TResult>,\n \"trigger\"\n> & { trigger: TTrigger };\n\ntype UnspooledJobDefinition<TPayload, TResult> = Omit<\n JobDefinition<TPayload, TResult>,\n \"trigger\"\n> & { trigger?: CronTriggerFor<TPayload> };\n","import type { JobContext } from \"./context\";\nimport type { BackoffPolicy, DeduplicatePolicy, PacePolicy } from \"./policies\";\nimport type { DeclaredTrigger, SpoolTrigger } from \"./trigger\";\n\nexport interface AnyJob {\n queue?: string;\n attempts?: number;\n backoff?: BackoffPolicy;\n trigger?: DeclaredTrigger;\n deduplicate?: DeduplicatePolicy<never>;\n pace?: PacePolicy;\n handler: (ctx: JobContext<never>) => Promise<unknown>;\n}\n\nexport interface AnySpoolFedJob extends AnyJob {\n trigger: DeclaredTrigger & { spool: SpoolTrigger };\n pace: PacePolicy;\n}\n\nexport function isSpoolFed(job: AnyJob): job is AnySpoolFedJob {\n return job.trigger?.spool !== undefined && job.pace !== undefined;\n}\n","const CONTINUATION = Symbol.for(\"ravenflow.continuation\");\n\nexport interface Continuation<TPayload> {\n readonly [CONTINUATION]: true;\n readonly params: TPayload;\n readonly delayMs?: number;\n readonly deduplicationId?: string;\n}\n\nexport interface ContinueOptions {\n delayMs?: number;\n deduplicationId?: string;\n}\n\nexport function continueWith<TPayload>(\n params: TPayload,\n options?: ContinueOptions,\n): Continuation<TPayload> {\n return {\n [CONTINUATION]: true,\n params,\n delayMs: options?.delayMs,\n deduplicationId: options?.deduplicationId,\n };\n}\n\nexport function isContinuation(value: unknown): value is Continuation<unknown> {\n return (\n isObject(value) && CONTINUATION in value && value[CONTINUATION] === true\n );\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n","export function namespacedDeduplicationId(\n jobName: string,\n deduplicationId: string,\n): string {\n return `${namespaceOf(jobName)}:${deduplicationId}`;\n}\n\nexport function deduplicationIdOf(\n jobName: string,\n namespacedId: string,\n): string {\n return namespacedId.slice(namespaceOf(jobName).length + 1);\n}\n\nfunction namespaceOf(jobName: string): string {\n return encodeURIComponent(jobName);\n}\n","export const MS_PER_PACE_UNIT = {\n perSecond: 1_000,\n perMinute: 60_000,\n perHour: 3_600_000,\n} as const;\n\nexport type PaceUnit = keyof typeof MS_PER_PACE_UNIT;\n\nexport const FASTEST_PACE_SPACING_MS = 1;\n\nexport const SLOWEST_PACE_SPACING_MS = 86_400_000;\n\nexport interface BackoffPolicy {\n type: \"fixed\" | \"exponential\";\n delayMs: number;\n jitter?: number;\n}\n\nexport type DeduplicatePolicy<TPayload> = true | ((params: TPayload) => string);\n\nexport type PacePolicy =\n | { perSecond: number; perMinute?: never; perHour?: never }\n | { perMinute: number; perSecond?: never; perHour?: never }\n | { perHour: number; perSecond?: never; perMinute?: never };\n\nexport function spacingMsOf(pace: PacePolicy): number {\n const { unit, releases } = releasesPerUnitOf(pace);\n return MS_PER_PACE_UNIT[unit] / releases;\n}\n\nexport function releasesWithin(ms: number, pace: PacePolicy): number {\n const { unit, releases } = releasesPerUnitOf(pace);\n return (ms * releases) / MS_PER_PACE_UNIT[unit];\n}\n\nfunction releasesPerUnitOf(pace: PacePolicy): {\n unit: PaceUnit;\n releases: number;\n} {\n if (pace.perSecond !== undefined) {\n return { unit: \"perSecond\", releases: pace.perSecond };\n }\n if (pace.perMinute !== undefined) {\n return { unit: \"perMinute\", releases: pace.perMinute };\n }\n return { unit: \"perHour\", releases: pace.perHour };\n}\n","import { z } from \"zod\";\n\nexport const wholeNumber = (min: number, error: string) =>\n z.number({ error }).int({ error }).min(min, { error });\n\nexport const numberBetween = (min: number, max: number, error: string) =>\n z.number({ error }).min(min, { error }).max(max, { error });\n\nexport const aFunction = z.custom<(...args: never[]) => unknown>(\n (value) => typeof value === \"function\",\n { error: \"must be a function.\" },\n);\n","import { z } from \"zod\";\nimport { FASTEST_PACE_SPACING_MS, MS_PER_PACE_UNIT, SLOWEST_PACE_SPACING_MS, type PaceUnit } from \"@/job\";\nimport { numberBetween } from \"./primitives\";\n\nconst ONE_UNIT = \"must declare exactly one of perSecond, perMinute or perHour.\";\n\nconst UNIT_NAMES: Record<PaceUnit, string> = { perSecond: \"second\", perMinute: \"minute\", perHour: \"hour\" };\n\nexport const paceSchema = z\n .strictObject({\n perSecond: releasesPer(\"perSecond\").optional(),\n perMinute: releasesPer(\"perMinute\").optional(),\n perHour: releasesPer(\"perHour\").optional(),\n })\n .refine(declaresOneUnit, { error: ONE_UNIT });\n\nfunction releasesPer(unit: PaceUnit) {\n const msPerUnit = MS_PER_PACE_UNIT[unit];\n const fastest = msPerUnit / FASTEST_PACE_SPACING_MS;\n return numberBetween(msPerUnit / SLOWEST_PACE_SPACING_MS, fastest, outOfRange(UNIT_NAMES[unit], fastest));\n}\n\nfunction outOfRange(unit: string, fastest: number): string {\n return `must be a number of releases per ${unit}, from one a day to ${fastest} — so 0.5 is one every two ${unit}s. Faster than one a millisecond cannot be spaced by Redis; slower than one a day is a pause, and there is a verb for that.`;\n}\n\nfunction declaresOneUnit(pace: Partial<Record<PaceUnit, number>>): boolean {\n const rates = [pace.perSecond, pace.perMinute, pace.perHour];\n return rates.filter((rate) => rate !== undefined).length === 1;\n}\n","import { releasesWithin, type PacePolicy, type SpoolTrigger } from \"@/job\";\n\nexport const DEFAULT_TICK_MS = 30_000;\n\nconst A_CLAIM_HOLDS_FOR_TICKS = 10;\n\nexport function tickMsOf(spool: SpoolTrigger): number {\n return spool.tickMs ?? DEFAULT_TICK_MS;\n}\n\nexport function claimHoldMsOf(spool: SpoolTrigger): number {\n return A_CLAIM_HOLDS_FOR_TICKS * tickMsOf(spool);\n}\n\nexport function inFlightCeilingOf(\n spool: SpoolTrigger,\n pace: PacePolicy,\n): number {\n return Math.ceil(releasesWithin(tickMsOf(spool), pace));\n}\n\nexport function roomUnderTheCeiling(\n spool: SpoolTrigger,\n pace: PacePolicy,\n inFlight: number,\n): number {\n return inFlightCeilingOf(spool, pace) - inFlight;\n}\n\nexport async function mayPull(spool: SpoolTrigger): Promise<boolean> {\n return (await spool.canPull?.()) ?? true;\n}\n","import { z } from \"zod\";\nimport { DEFAULT_TICK_MS } from \"@/spools/governor\";\nimport { aFunction, wholeNumber } from \"./primitives\";\n\nconst NO_NAME = \"must name the spool, whose backlog is rav:spool-backlog:<name>.\";\nconst COLON_IN_NAME =\n 'must not contain \":\" — it would break the job id of each item (spool:<name>:<_id>). Rename the spool.';\nconst NOT_A_TICK = `must be a whole number of milliseconds, one or more. Omit it to tick every ${DEFAULT_TICK_MS / 1_000} seconds.`;\nconst NOT_AN_EXPIRY = \"must be a whole number of milliseconds, one or more. Omit it to keep an item until it is released.\";\n\nexport const spoolNameSchema = z\n .string({ error: NO_NAME })\n .trim()\n .min(1, { error: NO_NAME })\n .refine((name) => !name.includes(\":\"), { error: COLON_IN_NAME });\n\nconst spoolSchema = z.strictObject({\n name: spoolNameSchema,\n tickMs: wholeNumber(1, NOT_A_TICK).optional(),\n canPull: aFunction.optional(),\n expireUnclaimedAfterMs: wholeNumber(1, NOT_AN_EXPIRY).optional(),\n});\n\nexport const triggerSchema = z.strictObject({\n cron: z.string({ error: \"must be a cron expression.\" }).optional(),\n spool: spoolSchema.optional(),\n});\n","import { z } from \"zod\";\nimport { paceSchema } from \"./pace.schema\";\nimport { aFunction, numberBetween } from \"./primitives\";\nimport { triggerSchema } from \"./trigger.schema\";\n\nconst NOT_A_JITTER =\n \"must be a number between 0 and 1: the share of its delay a retry may be brought forward by, so 0.2 retries between 80% and 100% of it.\";\nconst NOT_A_DEDUPLICATION =\n \"must be true or a function of the payload: true lets one run of the job be in flight at a time, a function one per id it returns. Omit it to deduplicate nothing.\";\n\nconst backoffSchema = z.strictObject({\n type: z.enum([\"fixed\", \"exponential\"], { error: \"must be 'fixed' or 'exponential'.\" }),\n delayMs: z.number({ error: \"must be a number of milliseconds.\" }),\n jitter: numberBetween(0, 1, NOT_A_JITTER).optional(),\n});\n\nconst deduplicateSchema = z.union([z.literal(true), aFunction], { error: NOT_A_DEDUPLICATION });\n\nexport const jobSchema = z.strictObject({\n queue: z.string({ error: \"must be a queue name.\" }).optional(),\n attempts: z.number({ error: \"must be a number.\" }).optional(),\n backoff: backoffSchema.optional(),\n trigger: triggerSchema.optional(),\n deduplicate: deduplicateSchema.optional(),\n pace: paceSchema.optional(),\n handler: aFunction,\n});\n","export const DEFAULT_COMPLETED_COUNT_RETENTION = 1000;\nexport const DEFAULT_FAILED_COUNT_RETENTION = 1000;\nexport const DEFAULT_JOB_RESULTS_RETENTION_HOURS = 14 * 24;\nexport const DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS = 90 * 24;\nexport const DEFAULT_GRACE_PERIOD_MS = 30_000;\n","import { z } from \"zod\";\nimport { jobSchema } from \"./job.schema\";\nimport {\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n} from \"../../constants\";\nimport { wholeNumber } from \"./primitives\";\n\nconst NOT_A_QUEUE = \"must be a queue name.\";\nconst NOT_A_JOB_COUNT = \"must be a whole number of jobs, zero or more. Omit it to use the default.\";\nconst NOT_A_LEVEL = \"must be one of trace, debug, info, warn, error, fatal.\";\nconst NOT_JOB_RESULTS_HOURS = notWholeHours(\"job results\", DEFAULT_JOB_RESULTS_RETENTION_HOURS);\nconst NOT_AGGREGATED_RESULTS_HOURS = notWholeHours(\"aggregated results\", DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS);\n\nconst loggerSchema = z.strictObject({\n level: z.enum([\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"], { error: NOT_A_LEVEL }).optional(),\n pretty: z.boolean({ error: \"must be true or false.\" }).optional(),\n});\n\nconst queuesRetentionSchema = z.strictObject({\n completedCount: wholeNumber(0, NOT_A_JOB_COUNT).optional(),\n failedCount: wholeNumber(0, NOT_A_JOB_COUNT).optional(),\n});\n\nexport const configSchema = z.strictObject({\n defaultQueue: z.string({ error: NOT_A_QUEUE }).min(1, { error: NOT_A_QUEUE }),\n jobs: z.record(z.string(), jobSchema, { error: \"must map each job's name to its declaration.\" }),\n logger: loggerSchema.optional(),\n queuesRetention: queuesRetentionSchema.optional(),\n jobResultsRetentionHours: wholeNumber(1, NOT_JOB_RESULTS_HOURS).optional(),\n aggregatedResultsRetentionHours: wholeNumber(1, NOT_AGGREGATED_RESULTS_HOURS).optional(),\n});\n\nfunction notWholeHours(kept: string, defaultHours: number): string {\n return `must be a whole number of hours, one or more. Omit it to keep ${kept} ${defaultHours / 24} days.`;\n}\n","import type { z } from \"zod\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\nimport { configSchema } from \"./schemas\";\n\nexport function shapeErrors(config: RavenflowConfig): string[] {\n const parsed = configSchema.safeParse(config);\n return parsed.success ? [] : parsed.error.issues.flatMap(describeIssue);\n}\n\nfunction describeIssue(issue: z.core.$ZodIssue): string[] {\n const path = issue.path.map(String);\n const inJob = path[0] === \"jobs\" && path.length > 1;\n const subject = inJob ? `\"${path[1]}\"` : \"config\";\n const field = inJob ? path.slice(2) : path;\n\n if (issue.code === \"unrecognized_keys\") {\n return issue.keys.map((key) => unknownKey(subject, [...field, key]));\n }\n return [[subject, field.join(\".\"), issue.message].filter(Boolean).join(\" \")];\n}\n\nfunction unknownKey(subject: string, field: string[]): string {\n return `${subject} ${field.join(\".\")} is not a key Ravenflow reads — check its spelling.`;\n}\n","import type { AnyJob } from \"@/job\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\n\nexport function declaredJobs(config: RavenflowConfig): Array<[string, AnyJob]> {\n const jobs: unknown = config.jobs;\n if (!isObject(jobs)) return [];\n return Object.entries(jobs as Record<string, AnyJob>).filter(([, job]) => isObject(job));\n}\n\nfunction isObject(value: unknown): value is object {\n return value !== null && typeof value === \"object\";\n}\n","import type { RavenflowConfig } from \"../ravenflow-config\";\nimport { declaredJobs } from \"./declared-jobs\";\nimport { spoolNameSchema } from \"./schemas\";\n\nexport function sharedSpoolErrors(config: RavenflowConfig): string[] {\n const ownerBySpool = new Map<string, string>();\n const errors: string[] = [];\n\n for (const [name, spoolName] of spoolNameOfEachJob(config)) {\n const owner = ownerBySpool.get(spoolName);\n if (owner !== undefined) {\n errors.push(sharedSpool(name, owner, spoolName));\n continue;\n }\n ownerBySpool.set(spoolName, name);\n }\n return errors;\n}\n\nfunction spoolNameOfEachJob(config: RavenflowConfig): Array<[string, string]> {\n return declaredJobs(config).flatMap(([name, job]): Array<[string, string]> => {\n const parsed = spoolNameSchema.safeParse(job.trigger?.spool?.name);\n return parsed.success ? [[name, parsed.data]] : [];\n });\n}\n\nfunction sharedSpool(name: string, owner: string, spoolName: string): string {\n return `\"${name}\" and \"${owner}\" are both fed by the spool \"${spoolName}\". Two jobs over one backlog would claim each other's items.`;\n}\n","import type { AnyJob } from \"@/job\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\nimport { declaredJobs } from \"./declared-jobs\";\n\nexport function spoolPaceErrors(config: RavenflowConfig): string[] {\n return declaredJobs(config)\n .filter(([, job]) => isSpoolFedWithoutAPace(job))\n .map(([name]) => `\"${name}\" pace is required: a spool drains at its job's pace.`);\n}\n\nfunction isSpoolFedWithoutAPace(job: AnyJob): boolean {\n return job.trigger?.spool !== undefined && job.pace === undefined;\n}\n","import type { RavenflowConfig } from \"../ravenflow-config\";\nimport { shapeErrors } from \"./shape-errors\";\nimport { sharedSpoolErrors } from \"./shared-spool-errors\";\nimport { spoolPaceErrors } from \"./spool-pace-errors\";\n\nexport function validateConfig(config: RavenflowConfig): void {\n throwIfAny([\n ...shapeErrors(config),\n ...spoolPaceErrors(config),\n ...sharedSpoolErrors(config),\n ]);\n}\n\nfunction throwIfAny(errors: string[]): void {\n if (errors.length === 0) return;\n throw new Error(`[ravenflow] Config validation failed:\\n - ${errors.join(\"\\n - \")}`);\n}\n","import pino from \"pino\";\n\nexport type Logger = pino.Logger;\n\nexport interface LoggerOptions {\n level?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n pretty?: boolean;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const isDev = process.env.NODE_ENV !== \"production\";\n const usePretty = options.pretty ?? isDev;\n\n return pino({\n level: options.level ?? (isDev ? \"debug\" : \"info\"),\n transport: usePretty\n ? {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"HH:MM:ss\",\n ignore: \"pid,hostname,job\",\n messageFormat: \"{if job}({job}) {end}{msg}\",\n },\n }\n : undefined,\n });\n}\n","import { MongoClient, type Db } from \"mongodb\";\n\nexport class MongoConnection {\n private client: MongoClient | null = null;\n private database: Db | null = null;\n private connecting: Promise<Db> | null = null;\n\n constructor(private readonly uri: string) {}\n\n async connect(): Promise<Db> {\n if (this.database) return this.database;\n this.connecting ??= this.openTheDatabase().catch((error: unknown) =>\n this.forgetTheAttempt(error),\n );\n return this.connecting;\n }\n\n async close(): Promise<void> {\n const closing = this.client;\n this.client = null;\n this.database = null;\n this.connecting = null;\n await closing?.close();\n }\n\n private async openTheDatabase(): Promise<Db> {\n const opened = new MongoClient(this.uri);\n await opened.connect();\n this.client = opened;\n this.database = opened.db();\n return this.database;\n }\n\n private forgetTheAttempt(error: unknown): never {\n this.connecting = null;\n throw error;\n }\n}\n","import type { RavenflowConfig } from \"@/config/ravenflow-config\";\nimport type { AnyJob } from \"@/job\";\n\nexport function declaredQueueNames(config: RavenflowConfig): string[] {\n const queueOfEachJob = Object.values(config.jobs).map((job) =>\n queueOf(job, config),\n );\n return [...new Set([config.defaultQueue, ...queueOfEachJob])];\n}\n\nexport function jobsDeclaredOn(\n queue: string,\n config: RavenflowConfig,\n): Record<string, AnyJob> {\n return Object.fromEntries(\n Object.entries(config.jobs).filter(\n ([, job]) => queueOf(job, config) === queue,\n ),\n );\n}\n\nfunction queueOf(job: AnyJob, config: RavenflowConfig): string {\n return job.queue ?? config.defaultQueue;\n}\n","import { Queue, type ConnectionOptions, type DefaultJobOptions } from \"bullmq\";\nimport type {\n RavenflowConfig,\n QueuesRetentionConfig,\n} from \"@/config/ravenflow-config\";\n\nimport {\n DEFAULT_COMPLETED_COUNT_RETENTION,\n DEFAULT_FAILED_COUNT_RETENTION,\n} from \"@/config/constants\";\n\nimport { declaredQueueNames } from \"./declared-queues\";\n\nexport type QueuesByName = Record<string, Queue>;\n\nexport interface QueueSettings {\n connection: ConnectionOptions;\n retention?: QueuesRetentionConfig;\n}\n\nexport function openQueues(\n config: RavenflowConfig,\n connection: ConnectionOptions,\n): QueuesByName {\n const settings = { connection, retention: config.queuesRetention };\n return Object.fromEntries(\n declaredQueueNames(config).map((name): [string, Queue] => [\n name,\n openQueue(name, settings),\n ]),\n );\n}\n\nexport function openQueue(name: string, settings: QueueSettings): Queue {\n return new Queue(name, {\n connection: settings.connection,\n defaultJobOptions: defaultJobOptionsFor(settings.retention),\n });\n}\n\nfunction defaultJobOptionsFor(\n retention: QueuesRetentionConfig = {},\n): DefaultJobOptions {\n return {\n removeOnComplete: {\n count: retention.completedCount ?? DEFAULT_COMPLETED_COUNT_RETENTION,\n },\n removeOnFail: {\n count: retention.failedCount ?? DEFAULT_FAILED_COUNT_RETENTION,\n },\n };\n}\n","import type { QueuesByName } from \"./open-queues\";\n\nexport async function closeQueues(queues: QueuesByName): Promise<void> {\n await Promise.all(Object.values(queues).map((queue) => queue.close()));\n}\n","import type { BackoffOptions, JobsOptions } from \"bullmq\";\nimport type { AnyJob, BackoffPolicy } from \"@/job\";\n\nexport function buildJobOptions(\n job: Pick<AnyJob, \"attempts\" | \"backoff\">,\n): JobsOptions {\n const options: JobsOptions = {};\n if (job.attempts !== undefined) options.attempts = job.attempts;\n if (job.backoff !== undefined) options.backoff = backoffOptions(job.backoff);\n\n return options;\n}\n\nfunction backoffOptions(backoff: BackoffPolicy): BackoffOptions {\n return {\n type: backoff.type,\n delay: backoff.delayMs,\n jitter: backoff.jitter,\n };\n}\n","const LINK_SEPARATOR = \".\";\n\nconst A_NUMBERED_LINK = /^(.+)\\.([1-9]\\d*)$/;\n\nexport interface LinkOfARun {\n runId: string;\n link: number;\n}\n\nexport function nextLinkIdOf(linkId: string): string {\n const { runId, link } = linkOfItsRun(linkId);\n return linkIdOf({ runId, link: link + 1 });\n}\n\nexport function linkIdOf({ runId, link }: LinkOfARun): string {\n if (link === 0) return runId;\n return `${asACustomJobId(runId)}${LINK_SEPARATOR}${link}`;\n}\n\nexport function linkOfItsRun(linkId: string): LinkOfARun {\n const numbered = A_NUMBERED_LINK.exec(linkId);\n if (numbered === null) return { runId: linkId, link: 0 };\n return { runId: numbered[1], link: Number(numbered[2]) };\n}\n\nfunction asACustomJobId(runId: string): string {\n if (holdsColonsBullmqRefuses(runId)) return encodeURIComponent(runId);\n return runId;\n}\n\nfunction holdsColonsBullmqRefuses(id: string): boolean {\n const parts = id.split(\":\").length;\n return parts !== 1 && parts !== 3;\n}\n","const JOB_PREFIX = \"job:\";\n\nexport type ControlKey = `job:${string}`;\n\nexport const CONTROL_KEY_MAX_LENGTH = 512;\n\nexport function controlKey(jobName: string): ControlKey {\n return `${JOB_PREFIX}${jobName}`;\n}\n\nexport function isControlKey(raw: unknown): raw is ControlKey {\n if (typeof raw !== \"string\" || raw.length > CONTROL_KEY_MAX_LENGTH) return false;\n return raw.startsWith(JOB_PREFIX) && raw.length > JOB_PREFIX.length;\n}\n\nexport function jobNameOf(key: ControlKey): string {\n return key.slice(JOB_PREFIX.length);\n}\n\nexport function validateControlName(name: string, caller: string): void {\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new Error(`${caller}: name must be a non-empty string`);\n }\n\n if (name.includes(\".\") || name.includes(\"$\")) {\n throw new Error(\n `${caller}: name cannot contain '.' or '$' (Mongo-reserved characters)`,\n );\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey, type ControlKey } from \"../control-key\";\nimport type { JobControls } from \"../levers\";\nimport type { ControlReads } from \"../types\";\n\nexport const CONTROL_CACHE_TTL_MS = 15_000;\n\nexport interface InvalidationSource {\n subscribe(onInvalidate: (key: ControlKey) => void): Promise<void>;\n}\n\nexport class ControlCache implements ControlReads {\n private readonly entries = new Map<\n ControlKey,\n {\n controls: JobControls;\n expiresAt: number;\n }\n >();\n private readonly inFlight = new Map<ControlKey, Promise<JobControls>>();\n private subscription: Promise<void> | null = null;\n\n constructor(\n private readonly parts: {\n source: ControlReads;\n invalidations: InvalidationSource;\n logger: Logger;\n },\n ) {}\n\n async read(jobName: string): Promise<JobControls> {\n const key = controlKey(jobName);\n const cached = this.entries.get(key);\n if (cached !== undefined && cached.expiresAt > Date.now()) {\n return cached.controls;\n }\n\n this.subscribeOnce();\n\n const reading = this.inFlight.get(key);\n if (reading !== undefined) return await reading;\n\n return await this.startRead(key, jobName);\n }\n\n invalidate(key: ControlKey): void {\n this.entries.delete(key);\n this.inFlight.delete(key);\n }\n\n clear(): void {\n this.entries.clear();\n this.inFlight.clear();\n }\n\n private startRead(key: ControlKey, jobName: string): Promise<JobControls> {\n const reading: Promise<JobControls> = this.parts.source.read(jobName).then(\n (controls) => {\n if (this.inFlight.get(key) === reading) this.keep(key, controls);\n return controls;\n },\n (err: unknown) => {\n if (this.inFlight.get(key) === reading) this.inFlight.delete(key);\n throw err;\n },\n );\n\n this.inFlight.set(key, reading);\n return reading;\n }\n\n private keep(key: ControlKey, controls: JobControls): void {\n this.entries.set(key, {\n controls,\n expiresAt: Date.now() + CONTROL_CACHE_TTL_MS,\n });\n this.inFlight.delete(key);\n }\n\n private subscribeOnce(): void {\n if (this.subscription) return;\n\n this.subscription = this.parts.invalidations\n .subscribe((key) => this.invalidate(key))\n .catch((err: unknown) => {\n this.parts.logger.warn(\n { err },\n \"[control] invalidation subscribe failed — changes arrive on the cache TTL instead\",\n );\n });\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport { ControlCache } from \"./cache\";\nimport type { ControlChannel } from \"./channel\";\nimport { controlKey } from \"./control-key\";\nimport type { JobControls } from \"./levers\";\nimport type { ControlStore } from \"./store\";\nimport type { JobControlPlane } from \"./types\";\n\nexport class ControlPlane implements JobControlPlane {\n private readonly cache: ControlCache;\n\n constructor(\n private readonly parts: {\n store: ControlStore;\n channel: ControlChannel;\n logger: Logger;\n },\n ) {\n this.cache = new ControlCache({\n source: parts.store,\n invalidations: parts.channel,\n logger: parts.logger,\n });\n }\n\n async read(jobName: string): Promise<JobControls> {\n return await this.cache.read(jobName);\n }\n\n async write(jobName: string, patch: Partial<JobControls>): Promise<void> {\n await this.parts.store.write(jobName, patch);\n this.cache.invalidate(controlKey(jobName));\n }\n\n async rehydrate(): Promise<void> {\n try {\n await this.parts.store.rehydrate();\n this.cache.clear();\n } catch (err) {\n this.parts.logger.error(\n { err },\n \"[control] rehydration failed — controls set before this boot may read as unset until they are written again\",\n );\n }\n }\n\n async close(): Promise<void> {\n await this.closeQuietly(\n () => this.parts.store.close(),\n \"[control] control store close failed\",\n );\n await this.closeQuietly(\n () => this.parts.channel.close(),\n \"[control] control channel close failed\",\n );\n }\n\n private async closeQuietly(\n close: () => Promise<void>,\n failure: string,\n ): Promise<void> {\n try {\n await close();\n } catch (err) {\n this.parts.logger.warn({ err }, failure);\n }\n }\n}\n","import { Redis, type Cluster } from \"ioredis\";\nimport type {\n ConnectionOptions,\n RedisOptions as BullMQRedisOptions,\n} from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nexport type RavenflowConnection = Redis | Cluster;\n\nexport type ConnectionRole = \"publisher\" | \"subscriber\" | \"store\";\n\nexport function openRavenflowConnection(\n connection: ConnectionOptions,\n role: ConnectionRole,\n logger: Logger,\n): RavenflowConnection {\n const opened = duplicateOrBuild(connection);\n opened.on(\"error\", (err: Error) => {\n logger.warn(\n { err, role },\n \"[ravenflow] redis connection error — ioredis reconnects, a command in flight fails\",\n );\n });\n return opened;\n}\n\nfunction duplicateOrBuild(connection: ConnectionOptions): RavenflowConnection {\n const candidate = connection as Partial<Redis>;\n if (typeof candidate.duplicate === \"function\") {\n return (connection as Redis).duplicate();\n }\n\n const { url, ...rest } = connection as BullMQRedisOptions;\n return url ? new Redis(url, rest) : new Redis(rest);\n}\n","import type { ConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport {\n openRavenflowConnection,\n type RavenflowConnection,\n} from \"../redis-connection\";\n\nimport { isControlKey, type ControlKey } from \"../control-key\";\n\nexport const CONTROL_INVALIDATION_CHANNEL = \"rav:controls:invalidate\";\n\nexport interface ControlPublisher {\n publish(key: ControlKey): Promise<void>;\n}\n\nexport class ControlChannel implements ControlPublisher {\n private publisher: RavenflowConnection | null = null;\n private subscriber: RavenflowConnection | null = null;\n\n constructor(\n private readonly connection: ConnectionOptions,\n private readonly logger: Logger,\n ) {}\n\n async publish(key: ControlKey): Promise<void> {\n this.publisher ??= this.open(\"publisher\");\n await this.publisher.publish(CONTROL_INVALIDATION_CHANNEL, key);\n }\n\n async subscribe(onInvalidate: (key: ControlKey) => void): Promise<void> {\n if (this.subscriber) {\n throw new Error(\"[ravenflow] ControlChannel is already subscribed\");\n }\n\n const subscriber = this.open(\"subscriber\");\n this.subscriber = subscriber;\n subscriber.on(\"message\", (channel: string, message: string) => {\n if (channel === CONTROL_INVALIDATION_CHANNEL) {\n this.deliver(message, onInvalidate);\n }\n });\n\n try {\n await this.listenOn(subscriber);\n } catch (err) {\n if (this.subscriber === subscriber) this.subscriber = null;\n throw err;\n }\n }\n\n async close(): Promise<void> {\n const open = [this.publisher, this.subscriber].filter(\n (connection) => connection !== null,\n );\n this.publisher = null;\n this.subscriber = null;\n\n await Promise.all(open.map(leave));\n }\n\n private deliver(\n message: string,\n onInvalidate: (key: ControlKey) => void,\n ): void {\n if (!isControlKey(message)) {\n this.logger.warn(\n { channel: CONTROL_INVALIDATION_CHANNEL, length: message.length },\n \"[control] invalidation message is not a control key — ignored\",\n );\n return;\n }\n\n onInvalidate(message);\n }\n\n private async listenOn(subscriber: RavenflowConnection): Promise<void> {\n try {\n await subscriber.subscribe(CONTROL_INVALIDATION_CHANNEL);\n } catch (err) {\n subscriber.disconnect();\n throw err;\n }\n }\n\n private open(role: \"publisher\" | \"subscriber\"): RavenflowConnection {\n return openRavenflowConnection(this.connection, role, this.logger);\n }\n}\n\nasync function leave(connection: RavenflowConnection): Promise<void> {\n try {\n await connection.quit();\n } catch {\n connection.disconnect();\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { ControlKey } from \"./control-key\";\n\nexport const LEVERS = [\"executionPaused\", \"triggerPaused\", \"ingestPaused\"] as const;\n\nexport type Lever = (typeof LEVERS)[number];\n\nexport type JobControls = Record<Lever, boolean>;\n\nexport const JOB_CONTROLS_OPEN: JobControls = {\n executionPaused: false,\n triggerPaused: false,\n ingestPaused: false,\n};\n\nexport function decodeLever(\n raw: string | undefined,\n key: ControlKey,\n logger: Logger,\n): boolean | undefined {\n if (raw === undefined) return undefined;\n\n let stored: unknown;\n try {\n stored = JSON.parse(raw);\n } catch (err) {\n logger.warn(\n { err, key },\n \"[control] stored control is not readable — treating it as unset\",\n );\n return undefined;\n }\n\n if (typeof stored === \"boolean\") return stored;\n\n logger.warn(\n { key, type: typeof stored },\n \"[control] stored control is not a boolean — treating it as unset\",\n );\n return undefined;\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey } from \"../control-key\";\nimport { decodeLever, JOB_CONTROLS_OPEN, type JobControls } from \"../levers\";\nimport type { StoredLever } from \"./control-hash\";\n\nexport type LiveControls = Map<string, JobControls>;\n\nexport function liveControls(\n stored: StoredLever[],\n logger: Logger,\n): LiveControls {\n const live: LiveControls = new Map();\n\n for (const held of stored) {\n const pulled = decodeLever(held.value, controlKey(held.jobName), logger);\n if (pulled === undefined) continue;\n\n const controls = live.get(held.jobName) ?? { ...JOB_CONTROLS_OPEN };\n controls[held.lever] = pulled;\n live.set(held.jobName, controls);\n }\n\n return live;\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey } from \"../control-key\";\nimport { LEVERS } from \"../levers\";\nimport type { ControlHash, LeverEntry } from \"./control-hash\";\nimport type { ControlMirror, MirroredControls } from \"./control-mirror\";\n\nexport const CONTROL_REHYDRATE_MAX_ENTRIES = 10_000;\n\nexport interface RehydrationParts {\n hash: ControlHash;\n mirror: ControlMirror;\n logger: Logger;\n}\n\nexport interface RehydrationReport {\n restored: number;\n alreadyLive: number;\n truncated: boolean;\n}\n\nexport async function rehydrateControls(\n parts: RehydrationParts,\n): Promise<RehydrationReport> {\n const levers = (await parts.mirror.listAll()).flatMap(pulledLevers);\n const report = await restoreMissing(parts.hash, levers);\n\n if (report.truncated) reportTruncation(parts.logger, levers.length);\n\n return report;\n}\n\nfunction pulledLevers(mirrored: MirroredControls): LeverEntry[] {\n const key = controlKey(mirrored._id);\n\n return LEVERS.filter((lever) => mirrored[lever] === true).map(\n (lever): LeverEntry => ({ key, lever, value: JSON.stringify(true) }),\n );\n}\n\nasync function restoreMissing(\n hash: ControlHash,\n levers: LeverEntry[],\n): Promise<RehydrationReport> {\n let restored = 0;\n let alreadyLive = 0;\n\n for (const lever of levers.slice(0, CONTROL_REHYDRATE_MAX_ENTRIES)) {\n if (await hash.writeIfAbsent(lever)) restored++;\n else alreadyLive++;\n }\n\n return {\n restored,\n alreadyLive,\n truncated: levers.length > CONTROL_REHYDRATE_MAX_ENTRIES,\n };\n}\n\nfunction reportTruncation(logger: Logger, held: number): void {\n logger.error(\n {\n fields: held,\n cap: CONTROL_REHYDRATE_MAX_ENTRIES,\n skipped: held - CONTROL_REHYDRATE_MAX_ENTRIES,\n },\n \"[control] the mirror holds more controls than rehydration will restore — the controls past the cap read as open until they are set again\",\n );\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { ControlPublisher } from \"../channel\";\nimport {\n controlKey,\n validateControlName,\n type ControlKey,\n} from \"../control-key\";\nimport { decodeLever, LEVERS, type JobControls } from \"../levers\";\nimport type { JobControlPlane } from \"../types\";\nimport type { ControlHash } from \"./control-hash\";\nimport type { ControlMirror } from \"./control-mirror\";\nimport { liveControls, type LiveControls } from \"./live-controls\";\nimport {\n rehydrateControls,\n type RehydrationReport,\n} from \"./rehydrate-controls\";\n\nexport interface ControlStoreParts {\n hash: ControlHash;\n publisher: ControlPublisher;\n mirror: ControlMirror;\n logger: Logger;\n}\n\nexport class ControlStore implements JobControlPlane {\n constructor(private readonly parts: ControlStoreParts) {}\n\n async read(jobName: string): Promise<JobControls> {\n const key = controlKey(jobName);\n const stored = await this.parts.hash.readLevers(key);\n\n return {\n executionPaused: this.isPulled(stored.get(\"executionPaused\"), key),\n triggerPaused: this.isPulled(stored.get(\"triggerPaused\"), key),\n ingestPaused: this.isPulled(stored.get(\"ingestPaused\"), key),\n };\n }\n\n async write(jobName: string, patch: Partial<JobControls>): Promise<void> {\n validateControlName(jobName, \"ControlStore.write\");\n refuseNonBooleanLevers(patch);\n const key = controlKey(jobName);\n\n await this.writeLevers(key, patch);\n await this.announce(key);\n await this.writeMirror(jobName, patch);\n }\n\n async readAll(): Promise<LiveControls> {\n return liveControls(\n await this.parts.hash.readEveryLever(),\n this.parts.logger,\n );\n }\n\n async rehydrate(): Promise<RehydrationReport> {\n return await rehydrateControls({\n hash: this.parts.hash,\n mirror: this.parts.mirror,\n logger: this.parts.logger,\n });\n }\n\n async close(): Promise<void> {\n await this.parts.hash.close();\n }\n\n private isPulled(raw: string | undefined, key: ControlKey): boolean {\n return decodeLever(raw, key, this.parts.logger) ?? false;\n }\n\n private async writeLevers(\n key: ControlKey,\n patch: Partial<JobControls>,\n ): Promise<void> {\n for (const lever of LEVERS) {\n const pulled = patch[lever];\n if (pulled === undefined) continue;\n\n await this.parts.hash.write({\n key,\n lever,\n value: JSON.stringify(pulled),\n });\n }\n }\n\n private async announce(key: ControlKey): Promise<void> {\n try {\n await this.parts.publisher.publish(key);\n } catch (err) {\n this.parts.logger.warn(\n { err, key },\n \"[control] invalidation publish failed — workers pick this up on the cache TTL instead\",\n );\n }\n }\n\n private async writeMirror(\n jobName: string,\n patch: Partial<JobControls>,\n ): Promise<void> {\n try {\n await this.parts.mirror.mirrorJobControls(jobName, patch);\n } catch (err) {\n this.parts.logger.error(\n { err, jobName, patch },\n \"[control] mirror write failed — the change is live but will not survive a Redis flush until the next successful write\",\n );\n }\n }\n}\n\nfunction refuseNonBooleanLevers(patch: Partial<JobControls>): void {\n for (const lever of LEVERS) {\n const pulled = patch[lever];\n if (pulled === undefined || typeof pulled === \"boolean\") continue;\n\n throw new Error(`ControlStore.write: ${lever} must be a boolean`);\n }\n}\n","import type { ConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport { openRavenflowConnection } from \"../redis-connection\";\n\nimport { isControlKey, jobNameOf, type ControlKey } from \"../control-key\";\nimport { LEVERS, type Lever } from \"../levers\";\n\nexport const CONTROL_HASH_KEY = \"rav:controls\";\n\nexport interface LeverEntry {\n key: ControlKey;\n lever: Lever;\n value: string;\n}\n\nexport interface StoredLever {\n jobName: string;\n lever: Lever;\n value: string;\n}\n\ninterface HashConnection {\n hgetall(key: string): Promise<Record<string, string>>;\n hmget(key: string, ...fields: string[]): Promise<Array<string | null>>;\n hset(key: string, field: string, value: string): Promise<number>;\n hsetnx(key: string, field: string, value: string): Promise<number>;\n quit(): Promise<unknown>;\n disconnect(): void;\n}\n\nexport class ControlHash {\n private connection: HashConnection | null = null;\n\n constructor(\n private readonly options: ConnectionOptions,\n private readonly logger: Logger,\n ) {}\n\n async readLevers(key: ControlKey): Promise<Map<Lever, string>> {\n const stored = await this.redis.hmget(\n CONTROL_HASH_KEY,\n ...LEVERS.map((lever) => controlField(key, lever)),\n );\n\n const pulled = new Map<Lever, string>();\n LEVERS.forEach((lever, index) => {\n const raw = stored[index];\n if (raw !== null && raw !== undefined) pulled.set(lever, raw);\n });\n return pulled;\n }\n\n async readEveryLever(): Promise<StoredLever[]> {\n return storedLevers(await this.redis.hgetall(CONTROL_HASH_KEY));\n }\n\n async write(entry: LeverEntry): Promise<void> {\n await this.redis.hset(\n CONTROL_HASH_KEY,\n controlField(entry.key, entry.lever),\n entry.value,\n );\n }\n\n async writeIfAbsent(entry: LeverEntry): Promise<boolean> {\n const written = await this.redis.hsetnx(\n CONTROL_HASH_KEY,\n controlField(entry.key, entry.lever),\n entry.value,\n );\n return written === 1;\n }\n\n async close(): Promise<void> {\n const open = this.connection;\n this.connection = null;\n if (!open) return;\n\n try {\n await open.quit();\n } catch {\n open.disconnect();\n }\n }\n\n private get redis(): HashConnection {\n this.connection ??= openRavenflowConnection(\n this.options,\n \"store\",\n this.logger,\n ) as HashConnection;\n return this.connection;\n }\n}\n\nexport function controlField(key: ControlKey, lever: Lever): string {\n return `${key}#${lever}`;\n}\n\nfunction storedLevers(fields: Record<string, string>): StoredLever[] {\n return Object.entries(fields).flatMap(([field, value]): StoredLever[] => {\n const held = leverOf(field);\n return held === undefined ? [] : [{ ...held, value }];\n });\n}\n\nfunction leverOf(field: string): { jobName: string; lever: Lever } | undefined {\n for (const lever of LEVERS) {\n const suffix = `#${lever}`;\n if (!field.endsWith(suffix)) continue;\n\n const key = field.slice(0, -suffix.length);\n if (isControlKey(key)) return { jobName: jobNameOf(key), lever };\n }\n return undefined;\n}\n","import type { Collection } from \"mongodb\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nimport type { JobControls } from \"../levers\";\n\nconst CONTROL_MIRROR_COLLECTION = \"rav:job-controls\";\n\nexport interface MirroredControls extends Partial<JobControls> {\n _id: string;\n updatedAt: Date;\n}\n\nexport interface ControlMirror {\n mirrorJobControls(\n jobName: string,\n patch: Partial<JobControls>,\n ): Promise<void>;\n listAll(): Promise<MirroredControls[]>;\n}\n\nexport function controlMirror(connection: MongoConnection): ControlMirror {\n const mirrorCollection = async (): Promise<Collection<MirroredControls>> => {\n const db = await connection.connect();\n return db.collection<MirroredControls>(CONTROL_MIRROR_COLLECTION);\n };\n\n return {\n mirrorJobControls: async (jobName, patch) => {\n const collection = await mirrorCollection();\n await collection.updateOne(\n { _id: jobName },\n { $set: { ...patch, updatedAt: new Date() } },\n { upsert: true },\n );\n },\n listAll: async () => (await mirrorCollection()).find().toArray(),\n };\n}\n","import type { ConnectionOptions as RedisConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nimport { ControlPlane } from \"./control-plane\";\nimport { ControlChannel } from \"./channel\";\nimport { ControlHash, ControlStore, controlMirror } from \"./store\";\n\nexport function initControlPlane(runtime: {\n redis: RedisConnectionOptions;\n mongo: MongoConnection;\n logger: Logger;\n}): ControlPlane {\n const channel = new ControlChannel(runtime.redis, runtime.logger);\n const store = new ControlStore({\n hash: new ControlHash(runtime.redis, runtime.logger),\n publisher: channel,\n mirror: controlMirror(runtime.mongo),\n logger: runtime.logger,\n });\n\n return new ControlPlane({ store, channel, logger: runtime.logger });\n}\n","import { ObjectId, type Collection, type Filter, type WithId } from \"mongodb\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nexport type SpoolItem = Record<string, unknown>;\n\nexport interface BacklogEntry {\n item: SpoolItem;\n claimedAt?: Date;\n}\n\nexport type StoredEntry = WithId<BacklogEntry>;\n\nexport interface SpoolPurgeReport {\n dropped: number;\n inFlight: number;\n}\n\nconst BACKLOG_COLLECTION_PREFIX = \"rav:spool-backlog:\";\n\nconst NEVER_CLAIMED: Filter<BacklogEntry> = { claimedAt: { $exists: false } };\n\nconst CLAIMED: Filter<BacklogEntry> = { claimedAt: { $type: \"date\" } };\n\nconst CLAIM_INDEX = { claimedAt: 1, _id: 1 } as const;\n\nconst OLDEST_FIRST = { _id: 1 } as const;\n\nconst MS_PER_SECOND = 1_000;\n\nexport class Backlog {\n constructor(\n readonly spoolName: string,\n private readonly connection: MongoConnection,\n ) {}\n\n async push(item: SpoolItem): Promise<string> {\n const backlog = await this.collection();\n const { insertedId } = await backlog.insertOne({ item });\n return insertedId.toHexString();\n }\n\n async pushMany(items: SpoolItem[]): Promise<string[]> {\n if (items.length === 0) return [];\n const backlog = await this.collection();\n const { insertedIds } = await backlog.insertMany(\n items.map((item) => ({ item })),\n );\n return items.map((_, position) => insertedIds[position].toHexString());\n }\n\n async purge(): Promise<SpoolPurgeReport> {\n const backlog = await this.collection();\n const { deletedCount } = await backlog.deleteMany(NEVER_CLAIMED);\n return {\n dropped: deletedCount,\n inFlight: await backlog.countDocuments(CLAIMED),\n };\n }\n\n async indexForTheClaim(): Promise<void> {\n const backlog = await this.collection();\n await backlog.createIndex(CLAIM_INDEX);\n }\n\n async countInFlight(): Promise<number> {\n const backlog = await this.collection();\n return backlog.countDocuments(CLAIMED);\n }\n\n async expireUnclaimedPushedBefore(pushedBefore: Date): Promise<number> {\n const backlog = await this.collection();\n const { deletedCount } = await backlog.deleteMany({\n ...NEVER_CLAIMED,\n _id: { $lt: ObjectId.createFromTime(secondsOf(pushedBefore)) },\n });\n return deletedCount;\n }\n\n async reclaimStaleClaims(\n claimedBefore: Date,\n now: Date,\n ): Promise<StoredEntry[]> {\n const staleClaim: Filter<BacklogEntry> = {\n claimedAt: { $lte: claimedBefore },\n };\n const backlog = await this.collection();\n const stale = await backlog.find(staleClaim).toArray();\n return this.claimAll(stale, staleClaim, now);\n }\n\n async claimOldestNeverClaimed(\n count: number,\n now: Date,\n ): Promise<StoredEntry[]> {\n if (count <= 0) return [];\n const backlog = await this.collection();\n const oldest = await backlog\n .find(NEVER_CLAIMED, { sort: OLDEST_FIRST, limit: count })\n .toArray();\n return this.claimAll(oldest, NEVER_CLAIMED, now);\n }\n\n async removeAll(ids: ObjectId[]): Promise<void> {\n if (ids.length === 0) return;\n const backlog = await this.collection();\n await backlog.deleteMany({ _id: { $in: ids } });\n }\n\n private async claimAll(\n entries: StoredEntry[],\n stillClaimable: Filter<BacklogEntry>,\n claimedAt: Date,\n ): Promise<StoredEntry[]> {\n if (entries.length === 0) return [];\n const ids = entries.map(({ _id }) => _id);\n const backlog = await this.collection();\n const { modifiedCount } = await backlog.updateMany(\n { _id: { $in: ids }, ...stillClaimable },\n { $set: { claimedAt } },\n );\n if (modifiedCount < entries.length) {\n return this.whatThisClaimTook(ids, claimedAt);\n }\n return entries;\n }\n\n private async whatThisClaimTook(\n ids: ObjectId[],\n claimedAt: Date,\n ): Promise<StoredEntry[]> {\n const backlog = await this.collection();\n return backlog.find({ _id: { $in: ids }, claimedAt }).toArray();\n }\n\n private async collection(): Promise<Collection<BacklogEntry>> {\n const db = await this.connection.connect();\n return db.collection<BacklogEntry>(collectionNameOf(this.spoolName));\n }\n}\n\nfunction collectionNameOf(spoolName: string): string {\n return `${BACKLOG_COLLECTION_PREFIX}${spoolName}`;\n}\n\nfunction secondsOf(moment: Date): number {\n return Math.floor(moment.getTime() / MS_PER_SECOND);\n}\n","import { ObjectId } from \"mongodb\";\nimport { linkIdOf, linkOfItsRun } from \"@/queues\";\n\nexport interface ItemLink {\n itemId: ObjectId;\n link: number;\n}\n\nconst SPOOL_JOB_ID_PREFIX = \"spool\";\n\nconst AN_ITEM_ID = /^[0-9a-f]{24}$/;\n\nexport function spoolJobId(\n spoolName: string,\n { itemId, link }: ItemLink,\n): string {\n return linkIdOf({\n runId: `${prefixOf(spoolName)}${itemId.toHexString()}`,\n link,\n });\n}\n\nexport function isALinkOfAnItem(spoolName: string, jobId: string): boolean {\n const prefix = prefixOf(spoolName);\n const { runId } = linkOfItsRun(jobId);\n return (\n runId.startsWith(prefix) && AN_ITEM_ID.test(runId.slice(prefix.length))\n );\n}\n\nexport function itemLinkOf(spoolName: string, jobId: string): ItemLink {\n if (!isALinkOfAnItem(spoolName, jobId)) {\n throw notALinkOfAnItem(spoolName, jobId);\n }\n const { runId, link } = linkOfItsRun(jobId);\n const itemId = runId.slice(prefixOf(spoolName).length);\n return { itemId: ObjectId.createFromHexString(itemId), link };\n}\n\nfunction prefixOf(spoolName: string): string {\n return `${SPOOL_JOB_ID_PREFIX}:${spoolName}:`;\n}\n\nfunction notALinkOfAnItem(spoolName: string, jobId: string): Error {\n return new Error(\n `[ravenflow] \"${jobId}\" is not the job id of a link of an item of the spool \"${spoolName}\".`,\n );\n}\n","import type { Queue } from \"bullmq\";\nimport type { ObjectId } from \"mongodb\";\n\nimport { itemLinkOf } from \"./spool-job-id\";\n\nexport class ItemRuns {\n constructor(\n private readonly queue: Queue,\n private readonly spoolName: string,\n ) {}\n\n async goOnTo(linkId: string): Promise<void> {\n const { itemId, link } = itemLinkOf(this.spoolName, linkId);\n const client = await this.queue.client;\n await client.set(this.currentLinkKeyOf(itemId), String(link));\n }\n\n async currentLinksOf(itemIds: ObjectId[]): Promise<number[]> {\n if (itemIds.length === 0) return [];\n const client = await this.queue.client;\n const links = await client.mget(\n itemIds.map((itemId) => this.currentLinkKeyOf(itemId)),\n );\n return links.map((link) => Number(link ?? 0));\n }\n\n async forget(itemIds: ObjectId[]): Promise<void> {\n if (itemIds.length === 0) return;\n const client = await this.queue.client;\n await client.del(itemIds.map((itemId) => this.currentLinkKeyOf(itemId)));\n }\n\n private currentLinkKeyOf(itemId: ObjectId): string {\n return this.queue.toKey(\n `rav:spool-run:${this.spoolName}:${itemId.toHexString()}`,\n );\n }\n}\n","import type { AnyJob } from \"@/job\";\nimport type { MongoConnection } from \"@/mongo/connection\";\nimport { Backlog } from \"@/spools\";\n\nexport function buildBacklog(\n definition: AnyJob,\n mongo: MongoConnection,\n): Backlog | undefined {\n const spool = definition.trigger?.spool;\n if (!spool) return undefined;\n return new Backlog(spool.name, mongo);\n}\n","import type { JobControlPlane, JobControls } from \"@/control-plane\";\nimport type { Backlog } from \"@/spools\";\n\nimport type {\n AnyJobControls,\n ClockFedControls,\n ExecutionControls,\n ProxiedJob,\n SpoolFedControls,\n} from \"./types\";\n\ntype SetLevers = (patch: Partial<JobControls>) => Promise<void>;\n\nexport function buildControls(\n job: ProxiedJob,\n plane: JobControlPlane,\n): AnyJobControls {\n const setLevers: SetLevers = (patch) => plane.write(job.name, patch);\n\n if (job.backlog) return spoolFedControls(setLevers, job.backlog);\n if (isClockFed(job)) return clockFedControls(setLevers);\n\n return executionControls(setLevers);\n}\n\nfunction isClockFed(job: ProxiedJob): boolean {\n return typeof job.definition.trigger?.cron === \"string\";\n}\n\nfunction executionControls(setLevers: SetLevers): ExecutionControls {\n return {\n pauseExecution: () => setLevers({ executionPaused: true }),\n resumeExecution: () => setLevers({ executionPaused: false }),\n };\n}\n\nfunction clockFedControls(setLevers: SetLevers): ClockFedControls {\n return {\n ...executionControls(setLevers),\n pauseTrigger: () => setLevers({ triggerPaused: true }),\n resumeTrigger: () => setLevers({ triggerPaused: false }),\n };\n}\n\nfunction spoolFedControls(\n setLevers: SetLevers,\n backlog: Backlog,\n): SpoolFedControls {\n return {\n ...clockFedControls(setLevers),\n pauseIngest: () => setLevers({ ingestPaused: true }),\n resumeIngest: () => setLevers({ ingestPaused: false }),\n purgeBacklog: () => backlog.purge(),\n };\n}\n","import type { JobsOptions } from \"bullmq\";\nimport { namespacedDeduplicationId } from \"@/job\";\n\nimport type { ProxiedJob, SendArguments } from \"./types\";\n\nexport function deduplicationOptions(\n job: ProxiedJob,\n sent: SendArguments,\n): JobsOptions {\n const deduplicationId = deduplicationIdOfTheSend(job, sent);\n if (deduplicationId === undefined) return {};\n return {\n deduplication: { id: namespacedDeduplicationId(job.name, deduplicationId) },\n };\n}\n\nfunction deduplicationIdOfTheSend(\n job: ProxiedJob,\n sent: SendArguments,\n): string | undefined {\n const givenId = sent.perCall.deduplicationId;\n if (givenId !== undefined) return givenId;\n\n const declared = job.definition.deduplicate;\n if (declared === undefined) return undefined;\n if (declared === true) return job.name;\n return declared(sent.payload as never);\n}\n","import { Job, type JobsOptions, type Queue } from \"bullmq\";\n\nimport { deduplicationOptions } from \"./deduplication\";\nimport type { ProxiedJob, SendArguments, SendOptions } from \"./types\";\n\ntype Send = (payload: unknown, options?: SendOptions) => Promise<Job>;\n\nexport function buildSend(job: ProxiedJob): Send {\n return async (payload, perCall = {}) => {\n const options = addOptions(job, { payload, perCall });\n const added = await job.queue.add(job.name, payload, options);\n if (!options.deduplication) return added;\n return jobHoldingTheDeduplicationId(job.queue, added);\n };\n}\n\nfunction addOptions(job: ProxiedJob, sent: SendArguments): JobsOptions {\n return {\n ...job.declaredOptions,\n ...queueingOptions(sent.perCall),\n ...deduplicationOptions(job, sent),\n };\n}\n\nfunction queueingOptions(perCall: SendOptions): JobsOptions {\n const options: JobsOptions = {};\n if (perCall.delayMs !== undefined) options.delay = perCall.delayMs;\n if (perCall.priority !== undefined) options.priority = perCall.priority;\n return options;\n}\n\nasync function jobHoldingTheDeduplicationId(\n queue: Queue,\n added: Job,\n): Promise<Job> {\n return (await Job.fromId(queue, String(added.id))) ?? added;\n}\n","import type { ControlReads } from \"@/control-plane\";\nimport type { Backlog, SpoolItem } from \"@/spools\";\n\nimport type { SpoolIngest } from \"./types\";\n\nexport function buildSpoolIngest(\n jobName: string,\n backlog: Backlog,\n controls: ControlReads,\n): SpoolIngest<SpoolItem> {\n return {\n push: async (item) => {\n await refuseIfIngestPaused(jobName, controls);\n return backlog.push(item);\n },\n pushMany: async (items) => {\n await refuseIfIngestPaused(jobName, controls);\n return backlog.pushMany(items);\n },\n };\n}\n\nasync function refuseIfIngestPaused(\n jobName: string,\n controls: ControlReads,\n): Promise<void> {\n const { ingestPaused } = await controls.read(jobName);\n if (ingestPaused) throw new SpoolIngestPausedError(jobName);\n}\n\nexport class SpoolIngestPausedError extends Error {\n constructor(public readonly job: string) {\n super(\n `[ravenflow] the spool feeding \"${job}\" is not accepting items: its ingest is paused. Call client.jobs.${job}.controls.resumeIngest() to reopen it.`,\n );\n this.name = \"SpoolIngestPausedError\";\n }\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\nimport type { SpoolItem } from \"@/spools\";\n\nimport { buildBacklog } from \"./build-backlog\";\nimport { buildControls } from \"./controls\";\nimport { buildSend } from \"./send\";\nimport { buildSpoolIngest } from \"./spool-ingest\";\nimport type {\n JobProxiesRuntime,\n JobSend,\n JobsProxy,\n ProxiedJob,\n SpoolIngest,\n} from \"./types\";\n\nexport function initJobProxies<TConfig extends RavenflowConfig>(\n config: TConfig,\n runtime: JobProxiesRuntime,\n): JobsProxy<TConfig[\"jobs\"]> {\n const proxies: Record<string, object> = {};\n\n for (const [name, definition] of Object.entries<AnyJob>(config.jobs)) {\n const job: ProxiedJob = {\n name,\n definition,\n queue: runtime.queues[definition.queue ?? config.defaultQueue],\n declaredOptions: buildJobOptions(definition),\n backlog: buildBacklog(definition, runtime.mongo),\n };\n\n proxies[name] = {\n ...buildSendOrIngest(job, runtime.controls),\n controls: buildControls(job, runtime.controls),\n };\n }\n\n return proxies as unknown as JobsProxy<TConfig[\"jobs\"]>;\n}\n\nfunction buildSendOrIngest(\n job: ProxiedJob,\n controls: ControlReads,\n): JobSend<unknown, unknown> | SpoolIngest<SpoolItem> {\n if (job.backlog) return buildSpoolIngest(job.name, job.backlog, controls);\n return { send: buildSend(job) };\n}\n","import type { ConnectionOptions as RedisConnectionOptions } from \"bullmq\";\nimport type { RavenflowConfig } from \"@/config\";\nimport { validateConfig } from \"@/config/validate-config\";\n\nimport type { JobsProxy } from \"./job-proxy\";\n\nimport { createLogger, type Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nimport { closeQueues, openQueues, type QueuesByName } from \"@/queues\";\nimport { ControlPlane, initControlPlane } from \"@/control-plane\";\n\nimport { initJobProxies } from \"./job-proxy\";\n\nexport class RavenflowClient<\n TConfig extends RavenflowConfig = RavenflowConfig,\n> {\n public readonly jobs: JobsProxy<TConfig[\"jobs\"]>;\n\n protected readonly redisConnectionOptions: RedisConnectionOptions;\n protected readonly mongoUri: string;\n\n protected readonly mongo: MongoConnection;\n\n protected readonly config: TConfig;\n protected readonly controlPlane: ControlPlane;\n protected readonly queues: QueuesByName;\n protected readonly logger: Logger;\n\n constructor(\n config: TConfig,\n options: {\n redis: RedisConnectionOptions;\n mongo: string;\n },\n ) {\n validateConfig(config);\n\n this.config = config;\n this.mongoUri = options.mongo;\n this.redisConnectionOptions = options.redis;\n\n this.logger = createLogger(config.logger);\n this.mongo = new MongoConnection(options.mongo);\n\n this.queues = openQueues(config, this.redisConnectionOptions);\n\n this.controlPlane = initControlPlane({\n redis: this.redisConnectionOptions,\n mongo: this.mongo,\n logger: this.logger,\n });\n\n this.jobs = initJobProxies(config, {\n queues: this.queues,\n mongo: this.mongo,\n controls: this.controlPlane,\n });\n }\n\n public async close(): Promise<void> {\n await this.controlPlane.close();\n await closeQueues(this.queues);\n await this.mongo.close();\n }\n}\n","import { RavenflowConfig } from \"@/config\";\nimport { RavenflowClient } from \"./ravenflow-client\";\n\nexport function createRavenflowClient<TConfig extends RavenflowConfig>(\n config: TConfig,\n options: ConstructorParameters<typeof RavenflowClient>[1],\n): RavenflowClient<TConfig> {\n return new RavenflowClient(config, options);\n}\n","export function describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import {\n isRedisInstance,\n type ConnectionOptions as RedisConnectionOptions,\n type RedisOptions,\n} from \"bullmq\";\nimport { isSpoolFed, type AnyJob, type AnySpoolFedJob } from \"@/job\";\nimport { inFlightCeilingOf } from \"@/spools\";\n\nimport type { JobResultsRecorderOpening } from \"./job-results-recorder\";\nimport type { SchedulerChanges } from \"./schedulers\";\n\nconst RAVENFLOW = `\n ██████╗ █████╗ ██╗ ██╗███████╗███╗ ██╗███████╗██╗ ██████╗ ██╗ ██╗\n ██╔══██╗██╔══██╗██║ ██║██╔════╝████╗ ██║██╔════╝██║ ██╔═══██╗██║ ██║\n ██████╔╝███████║██║ ██║█████╗ ██╔██╗ ██║█████╗ ██║ ██║ ██║██║ █╗ ██║\n ██╔══██╗██╔══██║╚██╗ ██╔╝██╔══╝ ██║╚██╗██║██╔══╝ ██║ ██║ ██║██║███╗██║\n ██║ ██║██║ ██║ ╚████╔╝ ███████╗██║ ╚████║██║ ███████╗╚██████╔╝╚███╔███╔╝\n ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝\n`;\n\nconst RULE = \"═\".repeat(85);\n\nconst FEEDS_IN_ORDER = [\"nothing\", \"clock\", \"spool\"] as const;\n\ninterface Feed {\n kind: (typeof FEEDS_IN_ORDER)[number];\n label: string;\n}\n\nexport interface BannerFacts {\n queue: string;\n concurrency: number;\n redis: RedisConnectionOptions;\n mongo: string;\n recorderOpening: JobResultsRecorderOpening;\n jobs: Record<string, AnyJob>;\n schedulers: SchedulerChanges;\n}\n\nexport function printBanner(facts: BannerFacts): void {\n console.log(\n [\n RAVENFLOW,\n RULE,\n \"[Config]\",\n ...configLines(facts),\n \"\",\n \"[Registered Jobs]\",\n ...registeredJobLines(facts.jobs),\n \"\",\n \"[Scheduled Jobs]\",\n ...schedulerLines(facts.schedulers),\n RULE,\n \"Ready to process jobs...\",\n ].join(\"\\n\"),\n );\n}\n\nfunction configLines(facts: BannerFacts): string[] {\n return [\n ` -> queue: ${facts.queue}`,\n ` -> concurrency: ${facts.concurrency}`,\n ` -> redis: ${addressOf(facts.redis)}`,\n ` -> mongo: ${mongoLineOf(facts)}`,\n ];\n}\n\nfunction addressOf(redis: RedisConnectionOptions): string {\n if (isRedisInstance(redis)) return \"an ioredis client\";\n\n const {\n url,\n host = \"localhost\",\n port = 6379,\n db = 0,\n } = redis as RedisOptions;\n return url ? withoutPassword(url) : `${host}:${port}/${db}`;\n}\n\nfunction mongoLineOf({ mongo, recorderOpening }: BannerFacts): string {\n const address = withoutPassword(mongo);\n if (!recorderOpening.opened) {\n return `${address} (job results are not recorded: ${recorderOpening.because})`;\n }\n return address;\n}\n\nfunction withoutPassword(uri: string): string {\n return uri.replace(/\\/\\/([^:/@]*):[^@]*@/, \"//$1:***@\");\n}\n\nfunction registeredJobLines(jobs: Record<string, AnyJob>): string[] {\n const lines = Object.entries(jobs)\n .map(([name, job]) => ({ name, feed: feedOf(job) }))\n .sort((a, b) => feedRank(a.feed) - feedRank(b.feed))\n .map(({ name, feed }) => ` . ${name}${feed.label}`);\n return lines.length > 0 ? lines : [\" (none)\"];\n}\n\nfunction feedOf(job: AnyJob): Feed {\n const cron = job.trigger?.cron;\n if (cron) return { kind: \"clock\", label: ` (↻ ${cron})` };\n if (isSpoolFed(job)) return { kind: \"spool\", label: spoolLabelOf(job) };\n return { kind: \"nothing\", label: \"\" };\n}\n\nfunction spoolLabelOf({ trigger, pace }: AnySpoolFedJob): string {\n const ceiling = inFlightCeilingOf(trigger.spool, pace);\n return ` (← ${trigger.spool.name}, ${ceiling} in flight at most)`;\n}\n\nfunction feedRank(feed: Feed): number {\n return FEEDS_IN_ORDER.indexOf(feed.kind);\n}\n\nfunction schedulerLines(changes: SchedulerChanges): string[] {\n const lines = [\n ...changes.added.map(({ name, pattern }) => ` + ${name} → ${pattern}`),\n ...changes.rescheduled.map(\n ({ name, pattern, previousPattern }) =>\n ` ↻ ${name} → ${pattern} (was ${previousPattern})`,\n ),\n ...changes.removed.map((name) => ` - ${name}`),\n ];\n return lines.length > 0 ? lines : [\" (no change)\"];\n}\n","import type { ConnectionOptions as RedisConnectionOptions } from \"bullmq\";\nimport {\n initControlPlane,\n type ControlPlane,\n type ControlReads,\n type JobControls,\n} from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nexport interface ControlPlaneReaderSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n logger: Logger;\n}\n\nexport class ControlPlaneReader implements ControlReads {\n private readonly mirrorConnection: MongoConnection;\n private readonly controlPlane: ControlPlane;\n\n constructor(settings: ControlPlaneReaderSettings) {\n this.mirrorConnection = new MongoConnection(settings.mongo);\n this.controlPlane = initControlPlane({\n redis: settings.redis,\n mongo: this.mirrorConnection,\n logger: settings.logger,\n });\n }\n\n async open(): Promise<void> {\n await this.controlPlane.rehydrate();\n await this.mirrorConnection.close();\n }\n\n read(jobName: string): Promise<JobControls> {\n return this.controlPlane.read(jobName);\n }\n\n async close(): Promise<void> {\n await this.controlPlane.close();\n await this.mirrorConnection.close();\n }\n}\n","import type { Logger } from \"@/logger\";\n\ninterface BullmqErrorSource {\n readonly name: string;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n}\n\nexport function logBullmqErrors(\n source: BullmqErrorSource,\n logger: Logger,\n): void {\n source.on(\"error\", (error) => {\n logger.error(\n { err: error, queue: source.name },\n `[ravenflow] BullMQ reported an error on \"${source.name}\".`,\n );\n });\n}\n","export const MONGODB_DEADLINE_ON_CLOSE_MS = 5_000;\n\nexport async function waitOrCutShort(\n waitingOnMongoDB: Promise<void>,\n cutItShort: () => Promise<void>,\n): Promise<void> {\n if (await settlesBeforeTheDeadline(waitingOnMongoDB)) return;\n await cutItShort();\n await waitingOnMongoDB;\n}\n\nasync function settlesBeforeTheDeadline(work: Promise<void>): Promise<boolean> {\n const deadline = new Promise<boolean>((resolve) => {\n setTimeout(() => resolve(false), MONGODB_DEADLINE_ON_CLOSE_MS).unref();\n });\n return Promise.race([work.then(() => true), deadline]);\n}\n","import { MongoBulkWriteError, type Collection } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\n\nimport { MONGODB_DEADLINE_ON_CLOSE_MS } from \"../mongodb-deadline-on-close\";\n\nimport type { JobResult } from \"./job-result\";\n\nconst FLUSH_INTERVAL_MS = 30_000;\n\nconst JOB_RESULTS_PER_BATCH = 1_000;\n\nconst MAX_UNWRITTEN_JOB_RESULTS = 5_000;\n\nconst PAUSE_BETWEEN_FINAL_FLUSHES_MS = 1_000;\n\nexport class BatchWriter {\n private buffered: JobResult[] = [];\n private writing = 0;\n private flushing: Promise<void> | null = null;\n private mayHoldJobs = true;\n private closed = false;\n private readonly heldJobs: Array<() => void> = [];\n private readonly timer: ReturnType<typeof setInterval>;\n\n constructor(\n private readonly collection: Collection<JobResult>,\n private readonly logger: Logger,\n ) {\n this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);\n this.timer.unref();\n }\n\n add(jobResult: JobResult): void {\n if (this.closed) return this.reportLost(1, \"it arrived after close()\");\n this.buffered.push(jobResult);\n if (this.buffered.length >= JOB_RESULTS_PER_BATCH) this.flush();\n }\n\n async waitForRoom(): Promise<void> {\n if (this.mustHoldJobs()) await this.holdJob();\n }\n\n stopHoldingJobs(): void {\n this.mayHoldJobs = false;\n this.releaseHeldJobs();\n }\n\n async close(): Promise<void> {\n clearInterval(this.timer);\n this.stopHoldingJobs();\n await this.flushUntil(Date.now() + MONGODB_DEADLINE_ON_CLOSE_MS);\n this.closed = true;\n this.dropWhatIsLeft();\n }\n\n private async holdJob(): Promise<void> {\n this.flush();\n await new Promise<void>((resolve) => this.heldJobs.push(resolve));\n }\n\n private mustHoldJobs(): boolean {\n return this.mayHoldJobs && this.unwritten() >= MAX_UNWRITTEN_JOB_RESULTS;\n }\n\n private unwritten(): number {\n return this.buffered.length + this.writing;\n }\n\n private releaseHeldJobs(): void {\n if (this.mustHoldJobs()) return;\n for (const release of this.heldJobs.splice(0)) release();\n }\n\n private async flush(): Promise<void> {\n if (this.flushing) return this.flushing;\n if (this.buffered.length === 0) return;\n\n this.flushing = this.writeBuffered();\n try {\n await this.flushing;\n } finally {\n this.flushing = null;\n this.releaseHeldJobs();\n }\n }\n\n private async writeBuffered(): Promise<void> {\n const batch = this.buffered;\n this.buffered = [];\n this.writing = batch.length;\n try {\n await this.collection.insertMany(batch, {\n ordered: false,\n ignoreUndefined: true,\n });\n } catch (error) {\n this.keepUnlessLost(batch, error);\n } finally {\n this.writing = 0;\n }\n }\n\n private keepUnlessLost(batch: JobResult[], error: unknown): void {\n const refused = countRefusedByMongo(error);\n if (refused > 0) return this.reportLost(refused, \"MongoDB refused them\");\n if (this.closed) return;\n\n this.buffered = [...batch, ...this.buffered];\n this.logger.warn(\n { err: error, jobResults: batch.length },\n \"[ravenflow] job results could not be written; they are kept for the next flush.\",\n );\n }\n\n private async flushUntil(deadline: number): Promise<void> {\n while (this.unwritten() > 0 && Date.now() < deadline) {\n await untilDeadline(this.flush(), deadline);\n if (this.unwritten() > 0) {\n await pause(\n Math.min(PAUSE_BETWEEN_FINAL_FLUSHES_MS, deadline - Date.now()),\n );\n }\n }\n }\n\n private dropWhatIsLeft(): void {\n const left = this.unwritten();\n this.buffered = [];\n if (left === 0) return;\n this.reportLost(\n left,\n `the final flush gave up after ${MONGODB_DEADLINE_ON_CLOSE_MS}ms`,\n );\n }\n\n private reportLost(count: number, why: string): void {\n this.logger.error(\n { lost: count },\n `[ravenflow] ${count} job results were not written: ${why}.`,\n );\n }\n}\n\nfunction countRefusedByMongo(error: unknown): number {\n if (!(error instanceof MongoBulkWriteError)) return 0;\n return [error.writeErrors].flat().length;\n}\n\nfunction untilDeadline(work: Promise<void>, deadline: number): Promise<void> {\n return Promise.race([work, pause(deadline - Date.now())]);\n}\n\nfunction pause(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, Math.max(0, ms)).unref();\n });\n}\n","import type { Collection, Db, IndexDescription } from \"mongodb\";\n\nimport type { JobResult } from \"./job-result\";\n\nconst JOB_RESULTS_COLLECTION = \"rav:job-results\";\n\nconst SECONDS_PER_HOUR = 3_600;\n\nconst ON_FINISHED_AT = { finishedAt: 1 } as const;\n\nconst QUERY_INDEXES: IndexDescription[] = [\n { key: { jobName: 1, finishedAt: -1 } },\n { key: { status: 1, finishedAt: -1 } },\n];\n\nexport function jobResultsCollection(db: Db): Collection<JobResult> {\n return db.collection<JobResult>(JOB_RESULTS_COLLECTION);\n}\n\nexport async function indexJobResults(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n await jobResultsCollection(db).createIndexes(QUERY_INDEXES);\n await expireJobResultsAfter(db, retentionHours * SECONDS_PER_HOUR);\n}\n\nasync function expireJobResultsAfter(db: Db, seconds: number): Promise<void> {\n const collection = jobResultsCollection(db);\n const index = await indexOnFinishedAt(collection);\n if (index === undefined) return createExpiryIndex(collection, seconds);\n if (index.expireAfterSeconds !== seconds) await changeExpiry(db, seconds);\n}\n\nasync function createExpiryIndex(\n collection: Collection<JobResult>,\n seconds: number,\n): Promise<void> {\n await collection.createIndex(ON_FINISHED_AT, { expireAfterSeconds: seconds });\n}\n\nasync function changeExpiry(db: Db, seconds: number): Promise<void> {\n await db.command({\n collMod: JOB_RESULTS_COLLECTION,\n index: { keyPattern: ON_FINISHED_AT, expireAfterSeconds: seconds },\n });\n}\n\nasync function indexOnFinishedAt(collection: Collection<JobResult>) {\n const indexes = await collection.indexes();\n return indexes.find((index) => isOnFinishedAtAlone(index.key));\n}\n\nfunction isOnFinishedAtAlone(key: Record<string, unknown>): boolean {\n const fields = Object.keys(key);\n return fields.length === 1 && key.finishedAt === 1;\n}\n","import { DelayedError, type Job } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\n\nconst DEFERRED_FOR_MS = 60_000;\n\nexport interface ExecutionGateRuntime {\n controls: ControlReads;\n token: string | undefined;\n}\n\nexport async function deferIfItsExecutionIsPaused(\n job: Job,\n runtime: ExecutionGateRuntime,\n): Promise<void> {\n const { executionPaused } = await runtime.controls.read(job.name);\n if (executionPaused) await deferTheJob(job, runtime.token);\n}\n\nasync function deferTheJob(\n job: Job,\n token: string | undefined,\n): Promise<never> {\n await job.moveToDelayed(Date.now() + DEFERRED_FOR_MS, token);\n throw new DelayedError();\n}\n","import { DelayedError, Worker, type Job, type Queue } from \"bullmq\";\nimport { spacingMsOf, type PacePolicy } from \"@/job\";\n\nconst US_PER_MS = 1_000;\n\nconst KEPT_PAST_THE_LAST_TURN_MS = 10_000;\n\nconst A_TURN_MAY_BE_LATE_BY_MS = 25;\n\nconst SLEPT_IN_PROCESS_UNDER_MS = 500;\n\nconst TAKE_A_TURN = `\nlocal at = redis.call('TIME')\nlocal now = tonumber(at[1]) * 1000000 + tonumber(at[2])\nlocal spacing = tonumber(ARGV[1])\nlocal mayBeLateBy = tonumber(ARGV[2])\nlocal sleptUnder = tonumber(ARGV[3])\nlocal keptMs = tonumber(ARGV[4])\nlocal turn = tonumber(redis.call('HGET', KEYS[2], 'ravPaceTurn'))\nif turn == nil or now - turn > mayBeLateBy then\n turn = tonumber(redis.call('GET', KEYS[1])) or now\n if turn < now then turn = now end\n local untilTheLastTurnMs = math.ceil((turn + spacing - now) / 1000)\n redis.call('SET', KEYS[1], turn + spacing, 'PX', untilTheLastTurnMs + keptMs)\nend\nlocal wait = turn - now\nif wait >= sleptUnder then\n redis.call('HSET', KEYS[2], 'ravPaceTurn', turn)\n return wait\nend\nredis.call('HDEL', KEYS[2], 'ravPaceTurn')\nif wait < 0 then return 0 end\nreturn wait\n`;\n\ninterface PaceRuntime {\n queue: Queue;\n token: string | undefined;\n shutdown: AbortSignal;\n}\n\nexport async function waitForItsTurn(\n job: Job,\n pace: PacePolicy | undefined,\n runtime: PaceRuntime,\n): Promise<void> {\n if (pace === undefined) return;\n if (runtime.shutdown.aborted) return handBackToWait();\n const waitMs = await takeATurn(job, spacingMsOf(pace), runtime.queue);\n if (waitMs >= SLEPT_IN_PROCESS_UNDER_MS) {\n return putOffInDelayed(job, waitMs - SLEPT_IN_PROCESS_UNDER_MS, runtime);\n }\n await sleep(waitMs, runtime.shutdown);\n if (runtime.shutdown.aborted) return handBackToWait();\n}\n\nasync function takeATurn(\n job: Job,\n spacingMs: number,\n queue: Queue,\n): Promise<number> {\n const client = await queue.client;\n const waitUs = await client.eval(\n TAKE_A_TURN,\n 2,\n queue.toKey(`rav:pace:${job.name}`),\n queue.toKey(String(job.id)),\n microseconds(spacingMs),\n microseconds(A_TURN_MAY_BE_LATE_BY_MS),\n microseconds(SLEPT_IN_PROCESS_UNDER_MS),\n String(KEPT_PAST_THE_LAST_TURN_MS),\n );\n return Number(waitUs) / US_PER_MS;\n}\n\nfunction microseconds(ms: number): string {\n return String(Math.round(ms * US_PER_MS));\n}\n\nasync function putOffInDelayed(\n job: Job,\n delayMs: number,\n runtime: PaceRuntime,\n): Promise<never> {\n await job.moveToDelayed(Date.now() + delayMs, runtime.token);\n throw new DelayedError();\n}\n\nfunction handBackToWait(): never {\n throw Worker.RateLimitError();\n}\n\nfunction sleep(ms: number, shutdown: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(wakeUp, ms);\n shutdown.addEventListener(\"abort\", wakeUp, { once: true });\n\n function wakeUp(): void {\n clearTimeout(timer);\n shutdown.removeEventListener(\"abort\", wakeUp);\n resolve();\n }\n });\n}\n","export interface ExecutionSignal {\n signal: AbortSignal;\n detach(): void;\n}\n\nexport function attachExecutionSignal(shutdown: AbortSignal): ExecutionSignal {\n const execution = new AbortController();\n const abort = () => execution.abort(shutdown.reason);\n\n if (shutdown.aborted) abort();\n else shutdown.addEventListener(\"abort\", abort, { once: true });\n\n return {\n signal: execution.signal,\n detach: () => shutdown.removeEventListener(\"abort\", abort),\n };\n}\n","import type { Job } from \"bullmq\";\nimport { format, inspect } from \"node:util\";\nimport type { Logger } from \"@/logger\";\n\ntype LogMethod = (...args: unknown[]) => void;\n\ntype ChildMethod = (...args: unknown[]) => Logger;\n\ntype Fields = Record<string, unknown>;\n\nexport function loggerFor(job: Job, logger: Logger): Logger {\n return new JobLogCopier(job).copyingLines(logger.child({ job: job.name }));\n}\n\nclass JobLogCopier {\n constructor(private readonly job: Job) {}\n\n copyingLines(logger: Logger): Logger {\n return new Proxy(logger, {\n get: (target, property) => {\n const value = Reflect.get(target, property);\n if (property === \"child\") {\n return this.childCopyingLines(target, value as ChildMethod);\n }\n if (!isLevelOf(target, property)) return value;\n return this.levelCopyingLines(target, property, value as LogMethod);\n },\n });\n }\n\n private childCopyingLines(parent: Logger, child: ChildMethod): ChildMethod {\n return (...args) => this.copyingLines(child.apply(parent, args));\n }\n\n private levelCopyingLines(\n logger: Logger,\n level: string,\n log: LogMethod,\n ): LogMethod {\n return (...args) => {\n log.apply(logger, args);\n if (!logger.isLevelEnabled(level)) return;\n this.copyLine(logger, lineOf(level, args, contextOf(logger)));\n };\n }\n\n private copyLine(logger: Logger, line: string): void {\n this.job.log(line).catch((error: unknown) => {\n logger.warn(\n { err: error },\n \"[ravenflow] a log line could not be copied into the job's logs.\",\n );\n });\n }\n}\n\nfunction isLevelOf(\n logger: Logger,\n property: string | symbol,\n): property is string {\n return (\n typeof property === \"string\" &&\n Object.keys(logger.levels.values).includes(property)\n );\n}\n\nfunction contextOf(logger: Logger): Fields {\n const bindings = Object.entries(logger.bindings());\n return Object.fromEntries(bindings.filter(([key]) => key !== \"job\"));\n}\n\nfunction lineOf(level: string, args: unknown[], context: Fields): string {\n const { message, fields } = partsOf(args, context);\n const time = `[${utcTimeOfDay(new Date())}]`;\n const words = [time, `${level.toUpperCase()}:`, message, inlined(fields)];\n return words.filter((word) => word !== \"\").join(\" \");\n}\n\nfunction partsOf(\n [first, ...rest]: unknown[],\n context: Fields,\n): { message: string; fields: Fields } {\n if (first instanceof Error) {\n return { message: format(...rest), fields: { ...context, err: first } };\n }\n if (typeof first === \"object\" && first !== null) {\n return { message: format(...rest), fields: { ...context, ...first } };\n }\n return { message: format(first, ...rest), fields: context };\n}\n\nfunction inlined(fields: Fields): string {\n if (Object.keys(fields).length === 0) return \"\";\n return inspect(fields, { breakLength: Infinity });\n}\n\nfunction utcTimeOfDay(date: Date): string {\n return date.toISOString().slice(11, 23);\n}\n","import type { Job } from \"bullmq\";\nimport type { ChainableCommander } from \"ioredis\";\nimport { deduplicationIdOf } from \"@/job\";\n\nconst RELEASE_IF_THE_LINK_HOLDS_IT = `\nif redis.call(\"GET\", KEYS[1]) == ARGV[1] then\n return redis.call(\"DEL\", KEYS[1])\nend\nreturn 0`;\n\nexport function deduplicationIdHeldBy(job: Job): string | undefined {\n const namespacedId = job.deduplicationId;\n if (namespacedId === undefined) return undefined;\n return deduplicationIdOf(job.name, namespacedId);\n}\n\nexport function releaseTheHoldOf(\n job: Job,\n transaction: ChainableCommander,\n): void {\n const namespacedId = job.deduplicationId;\n if (namespacedId === undefined) return;\n transaction.eval(\n RELEASE_IF_THE_LINK_HOLDS_IT,\n 1,\n `${job.queueQualifiedName}:de:${namespacedId}`,\n String(job.id),\n );\n}\n","import { Job, type JobsOptions, type Queue, type RedisClient } from \"bullmq\";\nimport type { ChainableCommander } from \"ioredis\";\nimport { namespacedDeduplicationId, type Continuation } from \"@/job\";\nimport { buildJobOptions, nextLinkIdOf } from \"@/queues\";\nimport { isALinkOfAnItem, ItemRuns } from \"@/spools\";\n\nimport type { Link } from \"./link\";\nimport { releaseTheHoldOf } from \"./link-deduplication\";\n\ninterface NextLink {\n jobName: string;\n id: string;\n params: unknown;\n options: JobsOptions;\n}\n\nexport async function enqueueNextLink(\n { job, definition }: Link,\n next: Continuation<unknown>,\n queue: Queue,\n): Promise<void> {\n const nextLink = nextLinkOf({ job, definition }, next);\n const spoolName = definition.trigger?.spool?.name;\n if (spoolName !== undefined && isALinkOfAnItem(spoolName, nextLink.id)) {\n refuseAnIdForTheRunOfAnItem(nextLink, next);\n await new ItemRuns(queue, spoolName).goOnTo(nextLink.id);\n }\n await addTheNextLink(job, nextLink, queue);\n}\n\nfunction nextLinkOf(\n { job, definition }: Link,\n next: Continuation<unknown>,\n): NextLink {\n const id = nextLinkIdOf(String(job.id));\n const options: JobsOptions = { ...buildJobOptions(definition), jobId: id };\n if (next.delayMs !== undefined) options.delay = next.delayMs;\n if (next.deduplicationId !== undefined) {\n const namespacedId = namespacedDeduplicationId(\n job.name,\n next.deduplicationId,\n );\n options.deduplication = { id: namespacedId };\n }\n return { jobName: job.name, id, params: next.params, options };\n}\n\nfunction refuseAnIdForTheRunOfAnItem(\n nextLink: NextLink,\n next: Continuation<unknown>,\n): void {\n if (next.deduplicationId === undefined) return;\n throw new Error(\n `[ravenflow] \"${nextLink.jobName}\" passes the deduplication id \"${next.deduplicationId}\" on to the next link of a spool item's run, but an item's run holds no deduplication id: each item runs under a job id of its own.`,\n );\n}\n\nasync function addTheNextLink(\n job: Job,\n nextLink: NextLink,\n queue: Queue,\n): Promise<void> {\n const transaction = (await queue.client).multi();\n releaseTheHoldOf(job, transaction);\n await addWithin(transaction, jobOf(nextLink, queue));\n await commit(transaction, nextLink);\n}\n\nfunction jobOf(nextLink: NextLink, queue: Queue): Job {\n const options = { ...queue.defaultJobOptions, ...nextLink.options };\n return new Job(\n queue,\n nextLink.jobName,\n nextLink.params,\n options,\n nextLink.id,\n );\n}\n\nasync function addWithin(\n transaction: ChainableCommander,\n job: Job,\n): Promise<void> {\n await job.addJob(transaction as unknown as RedisClient);\n}\n\nasync function commit(\n transaction: ChainableCommander,\n nextLink: NextLink,\n): Promise<void> {\n const replies = (await transaction.exec()) ?? [];\n for (const [error] of replies) {\n if (error !== null) throw nextLinkNotEnqueued(nextLink, error);\n }\n}\n\nfunction nextLinkNotEnqueued(nextLink: NextLink, cause: Error): Error {\n return new Error(\n `[ravenflow] the next link of \"${nextLink.jobName}\", ${nextLink.id}, could not be enqueued: ${cause.message}`,\n );\n}\n","import type { Job, Queue } from \"bullmq\";\nimport { continueWith, isContinuation, type JobContext } from \"@/job\";\nimport type { Logger } from \"@/logger\";\n\nimport { attachExecutionSignal } from \"./execution-signal\";\nimport { loggerFor } from \"./job-logger\";\nimport type { Link } from \"./link\";\nimport { deduplicationIdHeldBy } from \"./link-deduplication\";\nimport { enqueueNextLink } from \"./next-link\";\n\nexport interface LinkRuntime {\n shutdown: AbortSignal;\n logger: Logger;\n queue: Queue;\n}\n\nexport async function runLink(\n link: Link,\n runtime: LinkRuntime,\n): Promise<unknown> {\n const outcome = await callHandler(link, runtime);\n if (isContinuation(outcome)) {\n await enqueueNextLink(link, outcome, runtime.queue);\n return undefined;\n }\n return outcome;\n}\n\nasync function callHandler(\n { job, definition }: Link,\n runtime: LinkRuntime,\n): Promise<unknown> {\n const execution = attachExecutionSignal(runtime.shutdown);\n try {\n return await definition.handler(\n contextFor(job, runtime.logger, execution.signal),\n );\n } finally {\n execution.detach();\n }\n}\n\nfunction contextFor(\n job: Job,\n logger: Logger,\n signal: AbortSignal,\n): JobContext<never> {\n return {\n params: job.data as never,\n deduplicationId: deduplicationIdHeldBy(job),\n job,\n logger: loggerFor(job, logger),\n signal,\n continueWith,\n };\n}\n","import type { Job } from \"bullmq\";\n\nconst SKIPPED_BY_TRIGGER_PAUSE = \"skippedByTriggerPause\";\n\ntype Progress = Record<string, unknown>;\n\nexport function wasSkippedByATriggerPause(job: Job): boolean {\n return progressOf(job)[SKIPPED_BY_TRIGGER_PAUSE] === true;\n}\n\nexport async function markSkippedByATriggerPause(job: Job): Promise<void> {\n await job.updateProgress({\n ...progressOf(job),\n [SKIPPED_BY_TRIGGER_PAUSE]: true,\n });\n}\n\nfunction progressOf(job: Job): Progress {\n const { progress } = job;\n if (typeof progress !== \"object\" || progress === null) return {};\n return progress as Progress;\n}\n","import type { Job } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\n\nimport { markSkippedByATriggerPause } from \"./progress-marks\";\n\nexport async function isAnOccurrenceToSkip(\n job: Job,\n controls: ControlReads,\n): Promise<boolean> {\n return (\n wasProducedByItsScheduler(job) &&\n (await controls.read(job.name)).triggerPaused\n );\n}\n\nexport async function skipTheOccurrence(\n job: Job,\n logger: Logger,\n): Promise<void> {\n try {\n await markSkippedByATriggerPause(job);\n } catch (error) {\n warnOfAnUnmarkedSkip(job, error, logger);\n }\n}\n\nfunction wasProducedByItsScheduler(job: Job): boolean {\n return job.repeatJobKey !== undefined;\n}\n\nfunction warnOfAnUnmarkedSkip(job: Job, error: unknown, logger: Logger): void {\n logger.warn(\n { err: error, jobId: job.id },\n `[ravenflow] an occurrence of \"${job.name}\" was skipped, its trigger being paused, but the mark on it was not written to Redis.`,\n );\n}\n","import type { Job, Processor } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\n\nimport type { JobResultsRecorder } from \"../job-results-recorder\";\n\nimport { deferIfItsExecutionIsPaused } from \"./execution-gate\";\nimport { waitForItsTurn } from \"./pace-gate\";\nimport { runLink, type LinkRuntime } from \"./run-link\";\nimport { isAnOccurrenceToSkip, skipTheOccurrence } from \"./trigger-gate\";\n\nexport interface RouterRuntime extends LinkRuntime {\n jobs: Record<string, AnyJob>;\n controls: ControlReads;\n jobResultsRecorder: Pick<JobResultsRecorder, \"waitForRoom\">;\n}\n\nexport function routeByName(runtime: RouterRuntime): Processor {\n const declared = new Map(Object.entries(runtime.jobs));\n\n return async (job: Job, token?: string) => {\n const definition = declared.get(job.name);\n if (!definition) throw undeclaredJobError(job);\n if (await isAnOccurrenceToSkip(job, runtime.controls)) {\n return skipTheOccurrence(job, runtime.logger);\n }\n await deferIfItsExecutionIsPaused(job, {\n controls: runtime.controls,\n token,\n });\n await runtime.jobResultsRecorder.waitForRoom();\n await waitForItsTurn(job, definition.pace, {\n queue: runtime.queue,\n token,\n shutdown: runtime.shutdown,\n });\n startItsClock(job);\n return runLink({ job, definition }, runtime);\n };\n}\n\nfunction startItsClock(job: Job): void {\n job.processedOn = Date.now();\n}\n\nfunction undeclaredJobError(job: Job): Error {\n return new Error(\n `[ravenflow] \"${job.name}\" is not declared on \"${job.queueName}\", the queue this worker serves, so it has no handler to run.`,\n );\n}\n","export const JOB_RESULT_MAX_BYTES = 128 * 1024;\n\nexport const JOB_RESULT_MESSAGE_MAX_CHARS = 2000;\n\nexport const JOB_RESULT_STACK_MAX_CHARS = 8000;\n\nexport const JOB_RESULT_LOGS_MAX_CHARS = 500_000;\n","import type { Logger } from \"@/logger\";\n\nexport interface CauseChainEntry {\n message: string;\n name: string;\n}\n\nexport interface ExtractedError {\n /** Top-level message + \"\\nCaused by: \" + inner.message chain, truncated after joining. */\n message: string;\n /** Top-level stack trace only, truncated. Inner stacks are omitted to bound payload. */\n stack: string;\n /** Normalized chain beyond the top level. Empty array when the top Error has no `cause`. */\n causeChain: CauseChainEntry[];\n}\n\nexport interface ExtractMessageAndStackOptions {\n messageMaxChars: number;\n stackMaxChars: number;\n /** Depth cap to guard against cycles and pathological nesting. Default 5. */\n maxCauseDepth?: number;\n}\n\nconst DEFAULT_MAX_CAUSE_DEPTH = 5;\nconst NAME_MAX_CHARS = 64;\nconst CHAIN_SEPARATOR = \"\\nCaused by: \";\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\nfunction safeGet<T>(getter: () => T, fallback: T): T {\n try {\n return getter();\n } catch {\n return fallback;\n }\n}\n\nfunction isErrorLike(\n value: unknown,\n): value is { message: unknown; name?: unknown } {\n if (typeof value !== \"object\" || value === null) return false;\n return safeGet(() => \"message\" in value, false);\n}\n\nfunction normalizeEntry(\n value: unknown,\n messageMaxChars: number,\n): CauseChainEntry {\n const entryMax = Math.max(1, Math.floor(messageMaxChars / 2));\n if (isErrorLike(value)) {\n const rawMessage = safeGet<unknown>(\n () => (value as { message: unknown }).message,\n undefined,\n );\n const rawName = safeGet<unknown>(\n () => (value as { name?: unknown }).name,\n undefined,\n );\n const message = truncate(\n typeof rawMessage === \"string\"\n ? rawMessage\n : safeGet(() => String(rawMessage), \"\"),\n entryMax,\n );\n const name = truncate(\n typeof rawName === \"string\" ? rawName : \"Error\",\n NAME_MAX_CHARS,\n );\n return { message, name };\n }\n return {\n message: truncate(\n safeGet(() => String(value), \"\"),\n entryMax,\n ),\n name: \"NonError\",\n };\n}\n\nfunction walkCauseChain(\n top: { cause?: unknown },\n maxDepth: number,\n messageMaxChars: number,\n): { chain: CauseChainEntry[]; truncated: boolean } {\n const chain: CauseChainEntry[] = [];\n const seen = new WeakSet<object>();\n if (typeof top === \"object\" && top !== null) seen.add(top);\n\n let current: unknown = safeGet<unknown>(() => top.cause, undefined);\n let truncated = false;\n\n while (current !== undefined && current !== null) {\n if (chain.length >= maxDepth) {\n truncated = true;\n break;\n }\n if (typeof current === \"object\" && current !== null) {\n if (seen.has(current)) {\n truncated = true;\n break;\n }\n seen.add(current);\n }\n\n chain.push(normalizeEntry(current, messageMaxChars));\n\n const hasCause =\n typeof current === \"object\" &&\n current !== null &&\n safeGet(() => \"cause\" in (current as object), false);\n if (hasCause) {\n current = safeGet(\n () => (current as { cause?: unknown }).cause,\n undefined,\n );\n } else {\n break;\n }\n }\n\n return { chain, truncated };\n}\n\nexport function extractMessageAndStack(\n err: unknown,\n options: ExtractMessageAndStackOptions,\n logger: Logger,\n): ExtractedError {\n const { messageMaxChars, stackMaxChars } = options;\n const rawMaxDepth = options.maxCauseDepth ?? DEFAULT_MAX_CAUSE_DEPTH;\n const maxCauseDepth =\n Number.isFinite(rawMaxDepth) && rawMaxDepth >= 1\n ? Math.floor(rawMaxDepth)\n : DEFAULT_MAX_CAUSE_DEPTH;\n\n if (!(err instanceof Error)) {\n return {\n message: truncate(\n safeGet(() => String(err), \"\"),\n messageMaxChars,\n ),\n stack: \"\",\n causeChain: [],\n };\n }\n\n const topMessage = safeGet<string>(() => {\n const m = err.message;\n return typeof m === \"string\" ? m : String(m ?? \"\");\n }, \"\");\n const topStack = safeGet<string>(() => {\n const s = err.stack;\n return typeof s === \"string\" ? s : String(s ?? \"\");\n }, \"\");\n\n const { chain, truncated } = walkCauseChain(\n err as { cause?: unknown },\n maxCauseDepth,\n messageMaxChars,\n );\n\n if (truncated) {\n logger.warn(\n { topMessage: truncate(topMessage, 120) },\n \"extractMessageAndStack: maxCauseDepth reached, truncating cause chain.\",\n );\n }\n\n let joinedMessage = topMessage;\n for (const entry of chain) {\n joinedMessage += `${CHAIN_SEPARATOR}${entry.message}`;\n }\n\n return {\n message: truncate(joinedMessage, messageMaxChars),\n stack: truncate(topStack, stackMaxChars),\n causeChain: chain,\n };\n}\n","import { BSON } from \"mongodb\";\n\n/**\n * What a job handed in or handed back, made safe to store as **native BSON**\n * rather than as a serialised string — so `params.tenantId` is a field a query\n * can filter on instead of a substring to grep (D15).\n *\n * The value space is JSON's, whatever the handler declared: BullMQ holds `data`\n * and `returnvalue` as JSON in Redis, so a `Date` is already a string and a\n * `Map` already `{}` by the time this sees them.\n */\n\n/**\n * Whether to write the field at all, and what to write.\n *\n * `stored: false` rather than a sentinel value, because a field set to\n * `undefined` is one BSON drops — leaving a document whose missing key cannot\n * be told from one written before the key existed.\n */\nexport type Storable = { stored: true; value: unknown } | { stored: false };\n\n/**\n * The value to store, the marker that replaces it, or nothing.\n *\n * Two things a JSON value can be that BSON must not hold, and both are answered\n * by **replacing the whole value** rather than repairing it. A repaired value\n * is the failure this collection exists to end: a document that looks like the\n * truth and is not.\n *\n * `maxBytes` is measured in the bytes BSON will occupy, not in characters: the\n * cap bounds a document, and a document is bytes.\n */\nexport function storableValue(value: unknown, maxBytes: number): Storable {\n if (value === undefined) return { stored: false };\n\n const hostile = firstHostileKey(value);\n if (hostile !== null) {\n return {\n stored: true,\n value: { __ravenflow_omitted: true, hostileKey: hostile },\n };\n }\n\n const bytes = bsonBytesOf(value);\n if (bytes > maxBytes) {\n return { stored: true, value: { __ravenflow_omitted: true, bytes } };\n }\n\n return { stored: true, value };\n}\n\n/**\n * The first key BSON would store but nobody could query, or `null`.\n *\n * **Refused, not sanitised**, and the choice is load-bearing. Rewriting\n * `user.name` to `user_name` keeps the document and breaks the question: a\n * filter on the key the payload actually had comes back empty, which reads as\n * *\"no execution was given that\"* rather than as *\"this was not stored\"*. An\n * absent value asks to be looked into; a renamed one does not.\n *\n * A dot is the path separator every filter is written in, and a leading `$` is\n * how every update operator announces itself. A `$` anywhere else is ordinary.\n */\nfunction firstHostileKey(value: unknown): string | null {\n if (Array.isArray(value)) {\n for (const element of value) {\n const hostile = firstHostileKey(element);\n if (hostile !== null) return hostile;\n }\n return null;\n }\n\n if (value === null || typeof value !== \"object\") return null;\n\n for (const [key, nested] of Object.entries(value)) {\n if (key.includes(\".\") || key.startsWith(\"$\")) return key;\n const hostile = firstHostileKey(nested);\n if (hostile !== null) return hostile;\n }\n return null;\n}\n\n/**\n * Wrapped in a document because `calculateObjectSize` sizes documents and a\n * scalar is not one. The wrapper's overhead is counted, which errs a handful of\n * bytes towards refusing — the safe direction for a cap.\n */\nfunction bsonBytesOf(value: unknown): number {\n return BSON.calculateObjectSize({ v: value });\n}\n","import type { Job } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nimport { extractMessageAndStack } from \"./error-extraction\";\nimport {\n JOB_RESULT_MAX_BYTES,\n JOB_RESULT_MESSAGE_MAX_CHARS,\n JOB_RESULT_STACK_MAX_CHARS,\n} from \"./job-result-limits\";\nimport { storableValue } from \"./storable-value\";\n\nexport interface JobResult {\n jobName: string;\n queue: string;\n status: JobResultStatus;\n params?: unknown;\n result?: unknown;\n error?: JobResultError;\n logs?: string;\n finishedAt: Date;\n durationMs?: number;\n attemptsMade: number;\n}\n\nexport type JobResultStatus = \"succeeded\" | \"failed\";\n\nexport interface JobResultError {\n message: string;\n stack: string;\n causeChain?: Array<{ message: string; name: string }>;\n}\n\nexport function succeededJobResult(\n job: Job,\n result: unknown,\n logs: string,\n): JobResult {\n return {\n ...jobResultOf(job, logs),\n status: \"succeeded\",\n result: stored(result),\n error: lastErrorOf(job),\n };\n}\n\nexport function failedJobResult(\n job: Job,\n error: JobResultError,\n logs: string,\n): JobResult {\n return { ...jobResultOf(job, logs), status: \"failed\", error };\n}\n\nexport function willBeRetried(job: Job): boolean {\n return job.finishedOn === undefined;\n}\n\nexport function jobResultErrorOf(\n error: unknown,\n logger: Logger,\n): JobResultError {\n const { message, stack, causeChain } = extractMessageAndStack(\n error,\n {\n messageMaxChars: JOB_RESULT_MESSAGE_MAX_CHARS,\n stackMaxChars: JOB_RESULT_STACK_MAX_CHARS,\n },\n logger,\n );\n return {\n message,\n stack,\n causeChain: causeChain.length > 0 ? causeChain : undefined,\n };\n}\n\nfunction jobResultOf(job: Job, logs: string): Omit<JobResult, \"status\"> {\n return {\n jobName: job.name,\n queue: job.queueName,\n params: isNothing(job.data) ? undefined : stored(job.data),\n logs: logs === \"\" ? undefined : logs,\n finishedAt: finishedAtOf(job),\n durationMs: durationOf(job),\n attemptsMade: job.attemptsMade,\n };\n}\n\nfunction stored(value: unknown): unknown {\n const storable = storableValue(value, JOB_RESULT_MAX_BYTES);\n return storable.stored ? storable.value : undefined;\n}\n\nfunction isNothing(value: unknown): boolean {\n if (value === undefined || value === null) return true;\n if (typeof value !== \"object\" || Array.isArray(value)) return false;\n return Object.keys(value).length === 0;\n}\n\nfunction lastErrorOf(job: Job): JobResultError | undefined {\n if (!job.failedReason) return undefined;\n const stacks = job.stacktrace ?? [];\n return {\n message: job.failedReason.slice(0, JOB_RESULT_MESSAGE_MAX_CHARS),\n stack: (stacks[stacks.length - 1] ?? \"\").slice(\n 0,\n JOB_RESULT_STACK_MAX_CHARS,\n ),\n };\n}\n\nfunction finishedAtOf(job: Job): Date {\n return job.finishedOn === undefined ? new Date() : new Date(job.finishedOn);\n}\n\nfunction durationOf(job: Job): number | undefined {\n if (job.processedOn === undefined || job.finishedOn === undefined) {\n return undefined;\n }\n return job.finishedOn - job.processedOn;\n}\n","import type { Queue } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nexport async function captureJobLogs(\n queue: Queue,\n jobId: string,\n maxChars: number,\n logger: Logger,\n): Promise<string> {\n if (typeof jobId !== \"string\" || jobId.length === 0) {\n throw new Error(\"captureJobLogs: jobId must be a non-empty string\");\n }\n if (!Number.isInteger(maxChars) || maxChars <= 0) {\n throw new Error(\n `captureJobLogs: maxChars must be a positive integer, got ${maxChars}`,\n );\n }\n\n let logs: string[];\n try {\n const result = await queue.getJobLogs(jobId, 0, -1, true);\n logs = result.logs;\n } catch (err) {\n logger.warn(\n { err, jobId },\n \"[log-capture] failed to fetch job logs — returning empty string\",\n );\n return \"\";\n }\n\n const joined = logs.join(\"\\n\");\n if (joined.length <= maxChars) return joined;\n\n const originalLen = joined.length;\n let tailLen = maxChars;\n let marker = \"\";\n for (let i = 0; i < 3; i++) {\n marker = `[truncated — showing last ${tailLen} of ${originalLen} chars]\\n`;\n if (marker.length >= maxChars) {\n return marker.slice(0, maxChars);\n }\n tailLen = maxChars - marker.length;\n }\n return marker + joined.slice(-tailLen);\n}\n","import type { Job, Queue, Worker } from \"bullmq\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\n\nimport { wasSkippedByATriggerPause } from \"../job-router\";\n\nimport type { BatchWriter } from \"./batch-writer\";\nimport { JOB_RESULT_LOGS_MAX_CHARS } from \"./job-result-limits\";\nimport {\n failedJobResult,\n jobResultErrorOf,\n succeededJobResult,\n willBeRetried,\n} from \"./job-result\";\nimport { captureJobLogs } from \"./log-capture\";\n\nexport interface JobResultsListenerSettings {\n queue: Queue;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n batchWriter: Pick<BatchWriter, \"add\">;\n}\n\nexport class JobResultsListener {\n private readonly declared: Set<string>;\n private readonly resultsInProgress = new Set<Promise<void>>();\n\n constructor(private readonly settings: JobResultsListenerSettings) {\n this.declared = new Set(Object.keys(settings.jobs));\n }\n\n listenTo(worker: Worker): void {\n worker.on(\"completed\", (job, result) => {\n if (wasSkippedByATriggerPause(job)) return;\n this.recordIfDeclared(job, () => this.recordSuccess(job, result));\n });\n worker.on(\"failed\", (job, error) => {\n if (job === undefined || willBeRetried(job)) return;\n this.recordIfDeclared(job, () => this.recordFailure(job, error));\n });\n }\n\n async waitForResultsInProgress(): Promise<void> {\n while (this.resultsInProgress.size > 0) {\n await Promise.allSettled([...this.resultsInProgress]);\n }\n }\n\n private recordIfDeclared(job: Job, record: () => Promise<void>): void {\n if (!this.declared.has(job.name)) return;\n this.track(job, record);\n }\n\n private track(job: Job, record: () => Promise<void>): void {\n const inProgress = record()\n .catch((error: unknown) => this.warnOfALostResult(job, error))\n .finally(() => this.resultsInProgress.delete(inProgress));\n this.resultsInProgress.add(inProgress);\n }\n\n private async recordSuccess(job: Job, result: unknown): Promise<void> {\n const logs = await this.logsOf(job);\n this.settings.batchWriter.add(succeededJobResult(job, result, logs));\n }\n\n private async recordFailure(job: Job, error: Error): Promise<void> {\n const logs = await this.logsOf(job);\n const failure = jobResultErrorOf(error, this.settings.logger);\n this.settings.batchWriter.add(failedJobResult(job, failure, logs));\n }\n\n private async logsOf(job: Job): Promise<string> {\n return captureJobLogs(\n this.settings.queue,\n String(job.id),\n JOB_RESULT_LOGS_MAX_CHARS,\n this.settings.logger,\n );\n }\n\n private warnOfALostResult(job: Job, error: unknown): void {\n this.settings.logger.warn(\n { err: error, jobId: job.id },\n `[ravenflow] the job result of \"${job.name}\" #${job.id} could not be recorded.`,\n );\n }\n}\n","import type { Queue, Worker } from \"bullmq\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nimport { BatchWriter } from \"./batch-writer\";\nimport {\n indexJobResults,\n jobResultsCollection,\n} from \"./job-results-collection\";\nimport { JobResultsListener } from \"./job-results-listener\";\n\nexport interface JobResultsRecorderSettings {\n mongo: string;\n retentionHours: number;\n queue: Queue;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n}\n\nexport type JobResultsRecorderOpening =\n | { opened: true }\n | { opened: false; because: string };\n\ninterface ActiveRecording {\n writer: BatchWriter;\n listener: JobResultsListener;\n}\n\nexport class JobResultsRecorder {\n private readonly connection: MongoConnection;\n private recording: ActiveRecording | null = null;\n\n constructor(private readonly settings: JobResultsRecorderSettings) {\n this.connection = new MongoConnection(settings.mongo);\n }\n\n async open(worker: Worker): Promise<void> {\n try {\n this.recording = await this.openRecording(worker);\n } catch (error) {\n await this.connection.close();\n throw error;\n }\n }\n\n async waitForRoom(): Promise<void> {\n await this.recording?.writer.waitForRoom();\n }\n\n stopHoldingJobs(): void {\n this.recording?.writer.stopHoldingJobs();\n }\n\n async close(): Promise<void> {\n await this.closeRecording();\n await this.connection.close();\n }\n\n private async openRecording(worker: Worker): Promise<ActiveRecording> {\n const { queue, jobs, logger } = this.settings;\n const db = await this.connection.connect();\n await indexJobResults(db, this.settings.retentionHours);\n\n const writer = new BatchWriter(jobResultsCollection(db), logger);\n const listener = new JobResultsListener({\n queue,\n jobs,\n logger,\n batchWriter: writer,\n });\n listener.listenTo(worker);\n return { writer, listener };\n }\n\n private async closeRecording(): Promise<void> {\n const recording = this.recording;\n this.recording = null;\n if (!recording) return;\n\n await recording.listener.waitForResultsInProgress();\n await recording.writer.close();\n }\n}\n","import type { Collection, Db } from \"mongodb\";\n\nconst AGGREGATED_RESULTS_COLLECTION = \"rav:aggregated-results\";\n\nconst SECONDS_PER_HOUR = 3_600;\n\nconst THE_BEGINNING = new Date(0);\n\nexport interface AggregatedResult {\n minute: Date;\n job: { name: string; queue: string };\n succeeded: number;\n failed: number;\n}\n\nexport interface Minutes {\n from: Date;\n until: Date;\n}\n\nexport async function createAggregatedResultsIfMissing(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n if (await isMissing(db)) await createTimeSeries(db, retentionHours);\n}\n\nexport async function changeRetentionIfItDiffers(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n if (await retentionDiffers(db, retentionHours)) {\n await changeRetention(db, retentionHours);\n }\n}\n\nexport async function watermarkOf(db: Db): Promise<Date> {\n const newest = await aggregatedResultsCollection(db).findOne(\n {},\n { sort: { minute: -1 } },\n );\n if (newest === null) return THE_BEGINNING;\n return newest.minute;\n}\n\nexport async function replaceAggregatedResults(\n db: Db,\n minutes: Minutes,\n aggregatedResults: AggregatedResult[],\n): Promise<void> {\n const collection = aggregatedResultsCollection(db);\n await collection.deleteMany({\n minute: { $gte: minutes.from, $lt: minutes.until },\n });\n if (aggregatedResults.length === 0) return;\n await collection.insertMany(aggregatedResults, {\n forceServerObjectId: true,\n });\n}\n\nasync function isMissing(db: Db): Promise<boolean> {\n return (await collectionInfoOf(db)) === undefined;\n}\n\nasync function retentionDiffers(\n db: Db,\n retentionHours: number,\n): Promise<boolean> {\n const info = await collectionInfoOf(db);\n return info?.options?.expireAfterSeconds !== secondsOf(retentionHours);\n}\n\nasync function createTimeSeries(db: Db, retentionHours: number): Promise<void> {\n await db.createCollection(AGGREGATED_RESULTS_COLLECTION, {\n timeseries: {\n timeField: \"minute\",\n metaField: \"job\",\n granularity: \"minutes\",\n },\n expireAfterSeconds: secondsOf(retentionHours),\n });\n}\n\nasync function changeRetention(db: Db, retentionHours: number): Promise<void> {\n await db.command({\n collMod: AGGREGATED_RESULTS_COLLECTION,\n expireAfterSeconds: secondsOf(retentionHours),\n });\n}\n\nasync function collectionInfoOf(db: Db) {\n const [info] = await db\n .listCollections(\n { name: AGGREGATED_RESULTS_COLLECTION },\n { nameOnly: false },\n )\n .toArray();\n return info;\n}\n\nfunction secondsOf(hours: number): number {\n return hours * SECONDS_PER_HOUR;\n}\n\nfunction aggregatedResultsCollection(db: Db): Collection<AggregatedResult> {\n return db.collection<AggregatedResult>(AGGREGATED_RESULTS_COLLECTION);\n}\n","import type { Db } from \"mongodb\";\nimport {\n jobResultsCollection,\n type JobResult,\n} from \"@/worker/job-results-recorder\";\n\nimport {\n replaceAggregatedResults,\n watermarkOf,\n type AggregatedResult,\n type Minutes,\n} from \"./aggregated-results-collection\";\n\nconst MINUTE_MS = 60_000;\n\nconst HOUR_MS = 60 * MINUTE_MS;\n\nconst COUNT_MINUTES_OLDER_THAN_MS = 2 * MINUTE_MS;\n\nconst RECOUNT_WINDOW_MS = 10 * MINUTE_MS;\n\nexport async function aggregateJobResults(\n db: Db,\n now: Date,\n retentionHours: number,\n): Promise<void> {\n const minutes = await minutesToCount(db, now, retentionHours);\n await replaceAggregatedResults(db, minutes, await countByMinute(db, minutes));\n}\n\nasync function minutesToCount(\n db: Db,\n now: Date,\n retentionHours: number,\n): Promise<Minutes> {\n const until = minuteOf(now.getTime() - COUNT_MINUTES_OLDER_THAN_MS);\n const recountFrom = new Date(until.getTime() - RECOUNT_WINDOW_MS);\n const oldestKept = minuteOf(now.getTime() - retentionHours * HOUR_MS);\n const counted = earliestOf(await watermarkOf(db), recountFrom);\n return { from: latestOf(counted, oldestKept), until };\n}\n\nasync function countByMinute(\n db: Db,\n { from, until }: Minutes,\n): Promise<AggregatedResult[]> {\n return jobResultsCollection(db)\n .aggregate<AggregatedResult>([\n { $match: { finishedAt: { $gte: from, $lt: until } } },\n {\n $group: {\n _id: {\n minute: { $dateTrunc: { date: \"$finishedAt\", unit: \"minute\" } },\n name: \"$jobName\",\n queue: \"$queue\",\n },\n succeeded: { $sum: countWhenStatusIs(\"succeeded\") },\n failed: { $sum: countWhenStatusIs(\"failed\") },\n },\n },\n {\n $project: {\n _id: 0,\n minute: \"$_id.minute\",\n job: { name: \"$_id.name\", queue: \"$_id.queue\" },\n succeeded: 1,\n failed: 1,\n },\n },\n { $sort: { minute: 1, \"job.name\": 1 } },\n ])\n .toArray();\n}\n\nfunction countWhenStatusIs(status: JobResult[\"status\"]): object {\n return { $cond: [{ $eq: [\"$status\", status] }, 1, 0] };\n}\n\nfunction minuteOf(timestamp: number): Date {\n return new Date(Math.floor(timestamp / MINUTE_MS) * MINUTE_MS);\n}\n\nfunction earliestOf(first: Date, second: Date): Date {\n return first < second ? first : second;\n}\n\nfunction latestOf(first: Date, second: Date): Date {\n return first > second ? first : second;\n}\n","import {\n Queue,\n Worker,\n type ConnectionOptions as RedisConnectionOptions,\n} from \"bullmq\";\nimport type { Db } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nimport { logBullmqErrors } from \"../../log-bullmq-errors\";\nimport { waitOrCutShort } from \"../../mongodb-deadline-on-close\";\n\nimport { aggregateJobResults } from \"./aggregate-job-results\";\nimport {\n changeRetentionIfItDiffers,\n createAggregatedResultsIfMissing,\n} from \"./aggregated-results-collection\";\n\nconst AGGREGATOR_QUEUE = \"rav-internal-aggregate-results\";\n\nconst TICK_NAME = \"aggregate-results\";\n\nconst AT_THE_FIFTEENTH_SECOND = \"15 * * * * *\";\n\nconst ONE_TICK_AT_A_TIME = 1;\n\nconst TICKS_KEPT = 100;\n\nexport interface JobResultsAggregatorSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n retentionHours: number;\n logger: Logger;\n}\n\ninterface Ticking {\n aggregatorQueue: Queue;\n tickWorker: Worker;\n}\n\nexport class JobResultsAggregator {\n private readonly connection: MongoConnection;\n private ticking: Ticking | null = null;\n\n constructor(private readonly settings: JobResultsAggregatorSettings) {\n this.connection = new MongoConnection(settings.mongo);\n }\n\n async open(): Promise<void> {\n const aggregatorQueue = new Queue(AGGREGATOR_QUEUE, {\n connection: this.settings.redis,\n });\n logBullmqErrors(aggregatorQueue, this.settings.logger);\n const tickWorker = this.openTickWorker();\n this.ticking = { aggregatorQueue, tickWorker };\n await aggregatorQueue.setGlobalConcurrency(ONE_TICK_AT_A_TIME);\n await scheduleTicks(aggregatorQueue);\n }\n\n async stopTicking(): Promise<void> {\n const ticking = this.ticking;\n this.ticking = null;\n if (!ticking) return;\n\n await waitOrCutShort(ticking.tickWorker.close(), () =>\n this.connection.close(),\n );\n await ticking.aggregatorQueue.close();\n }\n\n async close(): Promise<void> {\n await this.stopTicking();\n await this.connection.close();\n }\n\n private openTickWorker(): Worker {\n const worker = new Worker(AGGREGATOR_QUEUE, () => this.tick(), {\n connection: this.settings.redis,\n });\n worker.on(\"failed\", (_tick, error) => this.warnOfAFailedTick(error));\n logBullmqErrors(worker, this.settings.logger);\n return worker;\n }\n\n private async tick(): Promise<void> {\n const db = await this.connection.connect();\n const { retentionHours } = this.settings;\n await createAggregatedResultsIfMissing(db, retentionHours);\n await this.applyTheConfiguredRetention(db);\n await aggregateJobResults(db, new Date(), retentionHours);\n }\n\n private async applyTheConfiguredRetention(db: Db): Promise<void> {\n try {\n await changeRetentionIfItDiffers(db, this.settings.retentionHours);\n } catch (error) {\n this.warnOfAnUnchangedRetention(error);\n }\n }\n\n private warnOfAFailedTick(error: Error): void {\n this.settings.logger.warn(\n { err: error },\n \"[ravenflow] a tick of the job results aggregator failed; its minutes are counted by the next tick that succeeds.\",\n );\n }\n\n private warnOfAnUnchangedRetention(error: unknown): void {\n this.settings.logger.warn(\n { err: error },\n `[ravenflow] the aggregated results' retention could not be changed to ${this.settings.retentionHours} hours; they are counted all the same, and kept as long as before.`,\n );\n }\n}\n\nasync function scheduleTicks(queue: Queue): Promise<void> {\n await queue.upsertJobScheduler(\n TICK_NAME,\n { pattern: AT_THE_FIFTEENTH_SECOND },\n {\n name: TICK_NAME,\n opts: {\n removeOnComplete: { count: TICKS_KEPT },\n removeOnFail: { count: TICKS_KEPT },\n },\n },\n );\n}\n","import type { Queue } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\nimport {\n ItemRuns,\n claimHoldMsOf,\n mayPull,\n roomUnderTheCeiling,\n spoolJobId,\n type Backlog,\n type StoredEntry,\n} from \"@/spools\";\n\nimport type { Stage } from \"./stage\";\n\nexport interface FeedingRuntime {\n backlog: Backlog;\n queue: Queue;\n controls: ControlReads;\n logger: Logger;\n}\n\ninterface Release {\n entry: StoredEntry;\n link: number;\n}\n\nexport async function feedSpool(\n stage: Stage,\n runtime: FeedingRuntime,\n): Promise<void> {\n await expireWhatWaitedTooLong(stage, runtime);\n if (await isItsTriggerPaused(stage, runtime.controls)) return;\n if (!(await mayPull(stage.spool))) return;\n const now = new Date();\n const staleRuns = await reclaimTheStaleRuns(stage, runtime, now);\n const newRuns = await claimWhatTheCeilingAllows(stage, runtime.backlog, now);\n await release(stage, [...staleRuns, ...newRuns], runtime.queue);\n}\n\nasync function expireWhatWaitedTooLong(\n stage: Stage,\n { backlog, logger }: FeedingRuntime,\n): Promise<void> {\n const { expireUnclaimedAfterMs } = stage.spool;\n if (expireUnclaimedAfterMs === undefined) return;\n const pushedBefore = new Date(Date.now() - expireUnclaimedAfterMs);\n const expired = await backlog.expireUnclaimedPushedBefore(pushedBefore);\n if (expired > 0) warnOfExpiredItems(stage, expired, logger);\n}\n\nfunction warnOfExpiredItems(\n stage: Stage,\n expired: number,\n logger: Logger,\n): void {\n const { name, expireUnclaimedAfterMs } = stage.spool;\n logger.warn(\n { spool: name, expired },\n `[ravenflow] ${expired} items of the spool \"${name}\" expired: they waited more than ${expireUnclaimedAfterMs} ms without being claimed.`,\n );\n}\n\nasync function isItsTriggerPaused(\n stage: Stage,\n controls: ControlReads,\n): Promise<boolean> {\n const { triggerPaused } = await controls.read(stage.jobName);\n return triggerPaused;\n}\n\nasync function reclaimTheStaleRuns(\n stage: Stage,\n { backlog, queue }: FeedingRuntime,\n now: Date,\n): Promise<Release[]> {\n const claimedBefore = new Date(now.getTime() - claimHoldMsOf(stage.spool));\n const entries = await backlog.reclaimStaleClaims(claimedBefore, now);\n const runs = new ItemRuns(queue, stage.spool.name);\n const currentLinks = await runs.currentLinksOf(entries.map(({ _id }) => _id));\n return entries.map((entry, position) => ({\n entry,\n link: currentLinks[position],\n }));\n}\n\nasync function claimWhatTheCeilingAllows(\n stage: Stage,\n backlog: Backlog,\n now: Date,\n): Promise<Release[]> {\n const inFlight = await backlog.countInFlight();\n const room = roomUnderTheCeiling(stage.spool, stage.pace, inFlight);\n const entries = await backlog.claimOldestNeverClaimed(room, now);\n return entries.map((entry) => ({ entry, link: 0 }));\n}\n\nasync function release(\n stage: Stage,\n releases: Release[],\n queue: Queue,\n): Promise<void> {\n if (releases.length === 0) return;\n await queue.addBulk(\n releases.map(({ entry, link }) => ({\n name: stage.jobName,\n data: entry.item,\n opts: {\n ...stage.jobOptions,\n jobId: spoolJobId(stage.spool.name, { itemId: entry._id, link }),\n },\n })),\n );\n}\n","import type { Job, Queue, Worker } from \"bullmq\";\nimport type { ObjectId } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\nimport type { MongoConnection } from \"@/mongo/connection\";\nimport {\n Backlog,\n ItemRuns,\n isALinkOfAnItem,\n itemLinkOf,\n type ItemLink,\n} from \"@/spools\";\n\nimport { willBeRetried } from \"../../job-results-recorder/job-result\";\n\nimport type { StagesByJobName } from \"./stage\";\n\nexport interface ItemRemovalsSettings {\n stages: StagesByJobName;\n queue: Queue;\n connection: MongoConnection;\n logger: Logger;\n}\n\ntype EndedLinksBySpoolName = Map<string, ItemLink[]>;\n\nexport class ItemRemovals {\n private endedLinks: EndedLinksBySpoolName = new Map();\n private removing: Promise<void> | null = null;\n\n constructor(private readonly settings: ItemRemovalsSettings) {}\n\n listenTo(worker: Worker): void {\n worker.on(\"completed\", (job) => this.noteTheEndOf(job));\n worker.on(\"failed\", (job) => {\n if (job === undefined || willBeRetried(job)) return;\n this.noteTheEndOf(job);\n });\n }\n\n async waitForRemovalsInProgress(): Promise<void> {\n while (this.removing) await this.removing;\n }\n\n private noteTheEndOf(job: Job): void {\n const stage = this.settings.stages.get(job.name);\n if (stage === undefined) return;\n const jobId = String(job.id);\n if (!isALinkOfAnItem(stage.spool.name, jobId)) return;\n\n this.addToEndedLinks(stage.spool.name, itemLinkOf(stage.spool.name, jobId));\n this.removing ??= this.removeTheItemsWhoseRunEnded();\n }\n\n private addToEndedLinks(spoolName: string, endedLink: ItemLink): void {\n const endedLinks = this.endedLinks.get(spoolName) ?? [];\n endedLinks.push(endedLink);\n this.endedLinks.set(spoolName, endedLinks);\n }\n\n private async removeTheItemsWhoseRunEnded(): Promise<void> {\n while (this.endedLinks.size > 0) {\n const batch = this.endedLinks;\n this.endedLinks = new Map();\n await Promise.all(\n [...batch].map(([spoolName, endedLinks]) =>\n this.removeWhereTheRunEnded(spoolName, endedLinks),\n ),\n );\n }\n this.removing = null;\n }\n\n private async removeWhereTheRunEnded(\n spoolName: string,\n endedLinks: ItemLink[],\n ): Promise<void> {\n try {\n const itemIds = await this.itemsWhoseRunEnded(spoolName, endedLinks);\n await new Backlog(spoolName, this.settings.connection).removeAll(itemIds);\n await new ItemRuns(this.settings.queue, spoolName).forget(itemIds);\n } catch (error) {\n this.warnOfItemsLeftBehind(spoolName, endedLinks, error);\n }\n }\n\n private async itemsWhoseRunEnded(\n spoolName: string,\n endedLinks: ItemLink[],\n ): Promise<ObjectId[]> {\n const runs = new ItemRuns(this.settings.queue, spoolName);\n const currentLinks = await runs.currentLinksOf(\n endedLinks.map(({ itemId }) => itemId),\n );\n return endedLinks\n .filter(({ link }, position) => currentLinks[position] <= link)\n .map(({ itemId }) => itemId);\n }\n\n private warnOfItemsLeftBehind(\n spoolName: string,\n endedLinks: ItemLink[],\n error: unknown,\n ): void {\n this.settings.logger.warn(\n { err: error, itemIds: endedLinks.map(({ itemId }) => String(itemId)) },\n `[ravenflow] ${endedLinks.length} links of the spool \"${spoolName}\" ended, but their items could not be removed from its backlog: they stay in it, and are released again ten ticks after their claim.`,\n );\n }\n}\n","import type { JobsOptions } from \"bullmq\";\nimport {\n isSpoolFed,\n type AnyJob,\n type PacePolicy,\n type SpoolTrigger,\n} from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\n\nexport interface Stage {\n jobName: string;\n spool: SpoolTrigger;\n pace: PacePolicy;\n jobOptions: JobsOptions;\n}\n\nexport type StagesByJobName = Map<string, Stage>;\n\nexport function stagesOf(jobs: Record<string, AnyJob>): StagesByJobName {\n return new Map(\n Object.entries(jobs).flatMap(([jobName, job]) =>\n stageEntriesOf(jobName, job),\n ),\n );\n}\n\nfunction stageEntriesOf(jobName: string, job: AnyJob): Array<[string, Stage]> {\n if (!isSpoolFed(job)) return [];\n const { trigger, pace } = job;\n const jobOptions = buildJobOptions(job);\n return [[jobName, { jobName, spool: trigger.spool, pace, jobOptions }]];\n}\n","import type { Queue } from \"bullmq\";\nimport { tickMsOf } from \"@/spools\";\n\nimport type { Stage, StagesByJobName } from \"./stage\";\n\nconst TICKS_KEPT = 100;\n\nexport async function reconcileTicks(\n feederQueue: Queue,\n stages: StagesByJobName,\n): Promise<void> {\n await removeTicksOfUndeclaredStages(feederQueue, stages);\n await Promise.all(\n [...stages.values()].map((stage) => scheduleTicks(feederQueue, stage)),\n );\n}\n\nasync function removeTicksOfUndeclaredStages(\n feederQueue: Queue,\n stages: StagesByJobName,\n): Promise<void> {\n const schedulers = await feederQueue.getJobSchedulers();\n const undeclared = schedulers.filter(({ key }) => !stages.has(key));\n await Promise.all(\n undeclared.map(({ key }) => feederQueue.removeJobScheduler(key)),\n );\n}\n\nasync function scheduleTicks(feederQueue: Queue, stage: Stage): Promise<void> {\n await feederQueue.upsertJobScheduler(\n stage.jobName,\n { every: tickMsOf(stage.spool) },\n {\n name: stage.jobName,\n opts: {\n removeOnComplete: { count: TICKS_KEPT },\n removeOnFail: { count: TICKS_KEPT },\n },\n },\n );\n}\n","import {\n Queue,\n Worker,\n type ConnectionOptions as RedisConnectionOptions,\n type Job,\n} from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\nimport { Backlog } from \"@/spools\";\n\nimport { logBullmqErrors } from \"../../log-bullmq-errors\";\nimport { waitOrCutShort } from \"../../mongodb-deadline-on-close\";\n\nimport { feedSpool } from \"./feed-spool\";\nimport { ItemRemovals } from \"./item-removals\";\nimport { stagesOf, type StagesByJobName } from \"./stage\";\nimport { reconcileTicks } from \"./ticks\";\n\nconst FEEDER_QUEUE_PREFIX = \"rav-internal-feed-spools-\";\n\nconst ONE_TICK_AT_A_TIME = 1;\n\nexport interface SpoolFeederSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n queue: Queue;\n controls: ControlReads;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n}\n\ninterface Feeding {\n feederQueue: Queue;\n tickWorker: Worker;\n}\n\nexport class SpoolFeeder {\n private readonly stages: StagesByJobName;\n private readonly connection: MongoConnection;\n private readonly itemRemovals: ItemRemovals;\n private readonly indexedBacklogs = new Set<string>();\n private feeding: Feeding | null = null;\n\n constructor(private readonly settings: SpoolFeederSettings) {\n this.stages = stagesOf(settings.jobs);\n this.connection = new MongoConnection(settings.mongo);\n this.itemRemovals = new ItemRemovals({\n stages: this.stages,\n queue: settings.queue,\n connection: this.connection,\n logger: settings.logger,\n });\n }\n\n async open(worker: Worker): Promise<void> {\n if (this.stages.size === 0) return;\n const feederQueue = new Queue(feederQueueNameOf(this.settings.queue), {\n connection: this.settings.redis,\n });\n logBullmqErrors(feederQueue, this.settings.logger);\n const tickWorker = this.openTickWorker(feederQueue.name);\n this.feeding = { feederQueue, tickWorker };\n this.itemRemovals.listenTo(worker);\n await feederQueue.setGlobalConcurrency(ONE_TICK_AT_A_TIME);\n await reconcileTicks(feederQueue, this.stages);\n }\n\n async stopTicking(): Promise<void> {\n const feeding = this.feeding;\n this.feeding = null;\n if (!feeding) return;\n\n await waitOrCutShort(feeding.tickWorker.close(), () =>\n this.connection.close(),\n );\n await feeding.feederQueue.close();\n }\n\n async finishTheRemovals(): Promise<void> {\n await waitOrCutShort(this.itemRemovals.waitForRemovalsInProgress(), () =>\n this.connection.close(),\n );\n }\n\n async close(): Promise<void> {\n await this.stopTicking();\n await this.finishTheRemovals();\n await this.connection.close();\n }\n\n private openTickWorker(feederQueueName: string): Worker {\n const worker = new Worker(feederQueueName, (tick) => this.tick(tick), {\n connection: this.settings.redis,\n });\n worker.on(\"failed\", (tick, error) => this.warnOfAFailedTick(tick, error));\n logBullmqErrors(worker, this.settings.logger);\n return worker;\n }\n\n private async tick(tick: Job): Promise<void> {\n const stage = this.stages.get(tick.name);\n if (stage === undefined) throw this.undeclaredSpoolError(tick);\n const backlog = new Backlog(stage.spool.name, this.connection);\n await this.indexOnce(backlog);\n await feedSpool(stage, {\n backlog,\n queue: this.settings.queue,\n controls: this.settings.controls,\n logger: this.settings.logger,\n });\n }\n\n private async indexOnce(backlog: Backlog): Promise<void> {\n if (this.indexedBacklogs.has(backlog.spoolName)) return;\n await backlog.indexForTheClaim();\n this.indexedBacklogs.add(backlog.spoolName);\n }\n\n private undeclaredSpoolError(tick: Job): Error {\n return new Error(\n `[ravenflow] no spool of \"${this.settings.queue.name}\" feeds \"${tick.name}\": its config does not declare one.`,\n );\n }\n\n private warnOfAFailedTick(tick: Job | undefined, error: Error): void {\n this.settings.logger.warn(\n { err: error },\n `[ravenflow] a tick of the spool feeding \"${tick?.name}\" failed; the next one releases what it did not.`,\n );\n }\n}\n\nfunction feederQueueNameOf(queue: Queue): string {\n return `${FEEDER_QUEUE_PREFIX}${queue.name}`;\n}\n","import { MetricsTime, Worker } from \"bullmq\";\n\nimport { routeByName, type RouterRuntime } from \"./job-router\";\nimport { logBullmqErrors } from \"./log-bullmq-errors\";\nimport type { RavenflowWorkerOptions } from \"./types\";\n\nconst DEFAULT_CONCURRENCY = 5;\n\nexport type WorkerRuntime = Omit<RouterRuntime, \"shutdown\">;\n\nexport function openWorker(\n options: RavenflowWorkerOptions,\n runtime: WorkerRuntime,\n): Worker {\n const shutdown = new AbortController();\n const route = routeByName({ ...runtime, shutdown: shutdown.signal });\n const worker = new Worker(options.queue, route, {\n connection: options.redis,\n concurrency: options.concurrency ?? DEFAULT_CONCURRENCY,\n metrics: { maxDataPoints: MetricsTime.ONE_WEEK },\n autorun: false,\n });\n abortWhenClosing(worker, shutdown);\n logBullmqErrors(worker, runtime.logger);\n return worker;\n}\n\nfunction abortWhenClosing(worker: Worker, shutdown: AbortController): void {\n worker.once(\"closing\", () => {\n shutdown.abort(new Error(\"[ravenflow] the worker is shutting down\"));\n });\n}\n","import type { JobSchedulerTemplateOptions, Queue } from \"bullmq\";\nimport { describeError } from \"@/describe-error\";\nimport type { AnyJob } from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\n\nexport interface CronSchedule {\n name: string;\n pattern: string;\n options: JobSchedulerTemplateOptions;\n}\n\nexport interface Rescheduled extends CronSchedule {\n previousPattern: string;\n}\n\nexport interface SchedulerChanges {\n added: CronSchedule[];\n rescheduled: Rescheduled[];\n removed: string[];\n}\n\ntype PatternsByScheduler = Map<string, string>;\n\nexport async function reconcileSchedulers(\n queue: Queue,\n jobs: Record<string, AnyJob>,\n): Promise<SchedulerChanges> {\n const declared = cronSchedulesOf(jobs);\n const existing = await patternsByScheduler(queue);\n const changes = changesBetween(declared, existing);\n\n await Promise.all(\n changes.removed.map((key) => queue.removeJobScheduler(key)),\n );\n await Promise.all(declared.map((schedule) => upsert(queue, schedule)));\n return changes;\n}\n\nfunction cronSchedulesOf(jobs: Record<string, AnyJob>): CronSchedule[] {\n return Object.entries(jobs).flatMap(([name, job]) => {\n const pattern = job.trigger?.cron;\n if (pattern === undefined) return [];\n return [{ name, pattern, options: buildJobOptions(job) }];\n });\n}\n\nasync function patternsByScheduler(queue: Queue): Promise<PatternsByScheduler> {\n const schedulers = await queue.getJobSchedulers();\n return new Map(\n schedulers.map(({ key, pattern }) => [key, pattern ?? \"no pattern\"]),\n );\n}\n\nfunction changesBetween(\n declared: CronSchedule[],\n existing: PatternsByScheduler,\n): SchedulerChanges {\n const declaredNames = new Set(declared.map(({ name }) => name));\n return {\n added: declared.filter(({ name }) => !existing.has(name)),\n rescheduled: declared.flatMap((schedule) =>\n reschedulingOf(schedule, existing),\n ),\n removed: [...existing.keys()].filter((key) => !declaredNames.has(key)),\n };\n}\n\nfunction reschedulingOf(\n schedule: CronSchedule,\n existing: PatternsByScheduler,\n): Rescheduled[] {\n const previousPattern = existing.get(schedule.name);\n if (previousPattern === undefined) return [];\n if (previousPattern === schedule.pattern) return [];\n return [{ ...schedule, previousPattern }];\n}\n\nasync function upsert(\n queue: Queue,\n { name, pattern, options }: CronSchedule,\n): Promise<void> {\n try {\n await queue.upsertJobScheduler(name, { pattern }, { name, opts: options });\n } catch (error) {\n throw new Error(\n `[ravenflow] \"${name}\" could not be scheduled on \"${pattern}\": ${describeError(error)}`,\n );\n }\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport { declaredQueueNames } from \"@/queues\";\n\nexport function refuseAQueueItsConfigDoesNotDeclare(\n queue: string,\n config: RavenflowConfig,\n): void {\n const declared = declaredQueueNames(config);\n if (declared.includes(queue)) return;\n\n const quoted = declared.map((name) => `\"${name}\"`).join(\", \");\n throw new Error(\n `[ravenflow] no job of this config runs on \"${queue}\": its queues are ${quoted}.`,\n );\n}\n","import type { Queue, Worker } from \"bullmq\";\n\nimport type { ControlPlaneReader } from \"./control-plane-reader\";\nimport type { JobResultsAggregator } from \"./internal-jobs/job-results-aggregator\";\nimport type { SpoolFeeder } from \"./internal-jobs/spool-feeder\";\nimport type { JobResultsRecorder } from \"./job-results-recorder\";\nimport type { MongoWatch } from \"./withdrawal\";\n\nexport interface Serving {\n queue: Queue;\n controlPlaneReader: ControlPlaneReader;\n jobResultsRecorder: JobResultsRecorder;\n jobResultsAggregator: JobResultsAggregator;\n spoolFeeder: SpoolFeeder;\n mongoWatch: MongoWatch;\n worker: Worker;\n}\n\nexport async function closeInOrder(serving: Serving): Promise<void> {\n await stopWatchingMongoDB(serving);\n await stopTheTicks(serving);\n await stopTheWorker(serving);\n await writeWhatItsJobsLeft(serving);\n await closeTheConnections(serving);\n}\n\nasync function stopWatchingMongoDB(serving: Serving): Promise<void> {\n await serving.mongoWatch.close();\n}\n\nasync function stopTheTicks(serving: Serving): Promise<void> {\n await Promise.all([\n serving.jobResultsAggregator.stopTicking(),\n serving.spoolFeeder.stopTicking(),\n ]);\n}\n\nasync function stopTheWorker(serving: Serving): Promise<void> {\n serving.jobResultsRecorder.stopHoldingJobs();\n await serving.worker.close();\n}\n\nasync function writeWhatItsJobsLeft(serving: Serving): Promise<void> {\n await Promise.all([\n serving.jobResultsRecorder.close(),\n serving.spoolFeeder.finishTheRemovals(),\n ]);\n}\n\nasync function closeTheConnections(serving: Serving): Promise<void> {\n await serving.spoolFeeder.close();\n await serving.jobResultsAggregator.close();\n await serving.controlPlaneReader.close();\n await serving.queue.close();\n}\n","import { MongoClient, type TopologyDescriptionChangedEvent } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\n\nconst THE_DRIVERS_RECOVERY_LAG_MS = 10_000;\n\nexport interface MongoWatchSettings {\n mongo: string;\n gracePeriodMs: number;\n logger: Logger;\n onDurableLoss: (unreachableForMs: number) => void;\n}\n\nexport class MongoWatch {\n private readonly client: MongoClient;\n private unreachableSince = 0;\n private graceTimer: ReturnType<typeof setTimeout> | null = null;\n private answeredOnce = false;\n\n constructor(private readonly settings: MongoWatchSettings) {\n this.client = new MongoClient(settings.mongo, {\n serverSelectionTimeoutMS:\n settings.gracePeriodMs + THE_DRIVERS_RECOVERY_LAG_MS,\n });\n }\n\n open(): void {\n this.client.on(\"topologyDescriptionChanged\", this.onTopologyChange);\n this.startTheGracePeriod();\n this.client.connect().catch((error: unknown) => this.noteItGaveUp(error));\n }\n\n async close(): Promise<void> {\n this.client.off(\"topologyDescriptionChanged\", this.onTopologyChange);\n this.stopTheGracePeriod();\n await this.client.close();\n }\n\n private readonly onTopologyChange = (\n event: TopologyDescriptionChangedEvent,\n ): void => {\n if (!event.newDescription.hasDataBearingServers) {\n this.noteUnreachable();\n return;\n }\n this.noteReachable();\n };\n\n private noteUnreachable(): void {\n if (this.graceTimer !== null) return;\n this.warnOfALoss();\n this.startTheGracePeriod();\n }\n\n private noteReachable(): void {\n if (this.graceTimer === null) return;\n if (this.answeredOnce) this.sayItIsBack();\n this.answeredOnce = true;\n this.stopTheGracePeriod();\n }\n\n private startTheGracePeriod(): void {\n this.unreachableSince = Date.now();\n this.graceTimer = setTimeout(\n () => this.settings.onDurableLoss(Date.now() - this.unreachableSince),\n this.settings.gracePeriodMs,\n );\n }\n\n private stopTheGracePeriod(): void {\n if (this.graceTimer === null) return;\n clearTimeout(this.graceTimer);\n this.graceTimer = null;\n }\n\n private noteItGaveUp(error: unknown): void {\n this.settings.logger.debug(\n { err: error },\n \"[ravenflow] the worker's watch on MongoDB stopped trying to connect.\",\n );\n }\n\n private warnOfALoss(): void {\n this.settings.logger.warn(\n { gracePeriodMs: this.settings.gracePeriodMs },\n \"[ravenflow] MongoDB is unreachable: the worker withdraws if it stays so for its whole grace period.\",\n );\n }\n\n private sayItIsBack(): void {\n this.settings.logger.info(\n { outageMs: Date.now() - this.unreachableSince },\n \"[ravenflow] MongoDB is reachable again, within the worker's grace period.\",\n );\n }\n}\n","import type { Logger } from \"@/logger\";\n\nconst EXIT_CODE_OF_A_WITHDRAWAL = 1;\n\nexport interface WithdrawingWorker {\n queue: string;\n logger: Logger;\n onWithdraw?: (reason: string) => void | Promise<void>;\n close: () => Promise<void>;\n}\n\nexport async function withdraw(\n worker: WithdrawingWorker,\n unreachableForMs: number,\n): Promise<void> {\n const reason = reasonOf(unreachableForMs);\n sayItWithdraws(worker, reason);\n await closeTheWorker(worker);\n process.exitCode = EXIT_CODE_OF_A_WITHDRAWAL;\n sayItHasWithdrawn(worker, reason);\n await callOnWithdraw(worker, reason);\n}\n\nfunction reasonOf(unreachableForMs: number): string {\n return `MongoDB has been unreachable for ${Math.round(unreachableForMs / 1_000)}s`;\n}\n\nfunction sayItWithdraws({ queue, logger }: WithdrawingWorker, reason: string) {\n logger.fatal(\n { reason },\n `[ravenflow] the worker serving \"${queue}\" withdraws: ${reason}. It takes no new job, and finishes the ones it holds.`,\n );\n}\n\nasync function closeTheWorker({\n queue,\n logger,\n close,\n}: WithdrawingWorker): Promise<void> {\n try {\n await close();\n } catch (error) {\n logger.error(\n { err: error },\n `[ravenflow] the worker serving \"${queue}\" could not close all it opened; it withdraws all the same.`,\n );\n }\n}\n\nfunction sayItHasWithdrawn(\n { queue, logger }: WithdrawingWorker,\n reason: string,\n) {\n logger.warn(\n { reason },\n `[ravenflow] the worker serving \"${queue}\" has withdrawn, and closed: the process exits with code ${EXIT_CODE_OF_A_WITHDRAWAL} once nothing else holds it.`,\n );\n}\n\nasync function callOnWithdraw(\n { logger, onWithdraw }: WithdrawingWorker,\n reason: string,\n): Promise<void> {\n try {\n await onWithdraw?.(reason);\n } catch (error) {\n logger.error(\n { err: error },\n \"[ravenflow] onWithdraw threw; the withdrawal itself stands.\",\n );\n }\n}\n","import type { Queue, Worker } from \"bullmq\";\nimport type { RavenflowConfig } from \"@/config\";\nimport {\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n DEFAULT_GRACE_PERIOD_MS,\n DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n} from \"@/config/constants\";\nimport { validateConfig } from \"@/config/validate-config\";\nimport { describeError } from \"@/describe-error\";\nimport type { AnyJob } from \"@/job\";\nimport { createLogger, type Logger } from \"@/logger\";\nimport { jobsDeclaredOn, openQueue } from \"@/queues\";\n\nimport { printBanner } from \"./banner\";\nimport { ControlPlaneReader } from \"./control-plane-reader\";\nimport { JobResultsAggregator } from \"./internal-jobs/job-results-aggregator\";\nimport { SpoolFeeder } from \"./internal-jobs/spool-feeder\";\nimport {\n JobResultsRecorder,\n type JobResultsRecorderOpening,\n} from \"./job-results-recorder\";\nimport { logBullmqErrors } from \"./log-bullmq-errors\";\nimport { openWorker } from \"./open-worker\";\nimport { reconcileSchedulers } from \"./schedulers\";\nimport { refuseAQueueItsConfigDoesNotDeclare } from \"./served-queue\";\nimport { closeInOrder, type Serving } from \"./serving\";\nimport type { RavenflowWorkerOptions } from \"./types\";\nimport { MongoWatch, withdraw } from \"./withdrawal\";\n\nexport class RavenflowWorker {\n private readonly config: RavenflowConfig;\n private readonly options: RavenflowWorkerOptions;\n private readonly jobs: Record<string, AnyJob>;\n private readonly logger: Logger;\n\n private serving: Serving | null = null;\n private starting: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(config: RavenflowConfig, options: RavenflowWorkerOptions) {\n validateConfig(config);\n refuseAQueueItsConfigDoesNotDeclare(options.queue, config);\n\n this.config = config;\n this.options = options;\n this.jobs = jobsDeclaredOn(options.queue, config);\n this.logger = createLogger(config.logger);\n }\n\n public async start(): Promise<void> {\n this.refuseASecondStart();\n\n const serving = this.openServing();\n this.serving = serving;\n this.starting = this.serveOrStop(serving);\n try {\n await this.starting;\n } finally {\n this.starting = null;\n }\n }\n\n public async close(): Promise<void> {\n await Promise.allSettled([this.starting]);\n if (this.serving === null) return;\n this.closing ??= this.stopServing(this.serving);\n await this.closing;\n }\n\n private async serveOrStop(serving: Serving): Promise<void> {\n try {\n await this.serve(serving);\n } catch (error) {\n await this.stopServing(serving);\n throw error;\n }\n }\n\n private async stopServing(serving: Serving): Promise<void> {\n try {\n await closeInOrder(serving);\n } finally {\n this.serving = null;\n this.closing = null;\n }\n }\n\n private refuseASecondStart(): void {\n if (!this.serving) return;\n throw new Error(\n `[ravenflow] this worker has already started on \"${this.options.queue}\".`,\n );\n }\n\n private openServing(): Serving {\n const queue = openQueue(this.options.queue, {\n connection: this.options.redis,\n retention: this.config.queuesRetention,\n });\n logBullmqErrors(queue, this.logger);\n const controlPlaneReader = this.buildControlPlaneReader();\n const jobResultsRecorder = this.buildJobResultsRecorder(queue);\n const worker = openWorker(this.options, {\n jobs: this.jobs,\n logger: this.logger,\n queue,\n controls: controlPlaneReader,\n jobResultsRecorder,\n });\n return {\n queue,\n controlPlaneReader,\n jobResultsRecorder,\n jobResultsAggregator: this.buildJobResultsAggregator(),\n spoolFeeder: this.buildSpoolFeeder(queue, controlPlaneReader),\n mongoWatch: this.buildMongoWatch(),\n worker,\n };\n }\n\n private buildControlPlaneReader(): ControlPlaneReader {\n return new ControlPlaneReader({\n redis: this.options.redis,\n mongo: this.options.mongo,\n logger: this.logger,\n });\n }\n\n private buildJobResultsRecorder(queue: Queue): JobResultsRecorder {\n return new JobResultsRecorder({\n mongo: this.options.mongo,\n retentionHours:\n this.config.jobResultsRetentionHours ??\n DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n queue,\n jobs: this.jobs,\n logger: this.logger,\n });\n }\n\n private buildJobResultsAggregator(): JobResultsAggregator {\n return new JobResultsAggregator({\n redis: this.options.redis,\n mongo: this.options.mongo,\n retentionHours:\n this.config.aggregatedResultsRetentionHours ??\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n logger: this.logger,\n });\n }\n\n private buildSpoolFeeder(\n queue: Queue,\n controls: ControlPlaneReader,\n ): SpoolFeeder {\n return new SpoolFeeder({\n redis: this.options.redis,\n mongo: this.options.mongo,\n queue,\n controls,\n jobs: this.jobs,\n logger: this.logger,\n });\n }\n\n private buildMongoWatch(): MongoWatch {\n return new MongoWatch({\n mongo: this.options.mongo,\n gracePeriodMs:\n this.options.withdrawal?.afterMs ?? DEFAULT_GRACE_PERIOD_MS,\n logger: this.logger,\n onDurableLoss: (unreachableForMs) =>\n this.beginAWithdrawal(unreachableForMs),\n });\n }\n\n private beginAWithdrawal(unreachableForMs: number): void {\n const withdrawing = {\n queue: this.options.queue,\n logger: this.logger,\n onWithdraw: this.options.withdrawal?.onWithdraw,\n close: () => this.close(),\n };\n void withdraw(withdrawing, unreachableForMs);\n }\n\n private async serve({\n queue,\n controlPlaneReader,\n jobResultsRecorder,\n jobResultsAggregator,\n spoolFeeder,\n mongoWatch,\n worker,\n }: Serving): Promise<void> {\n mongoWatch.open();\n await controlPlaneReader.open();\n const recorderOpening = await this.openRecorder(jobResultsRecorder, worker);\n await jobResultsAggregator.open();\n await spoolFeeder.open(worker);\n const schedulers = await reconcileSchedulers(queue, this.jobs);\n this.takeJobs(worker);\n await worker.waitUntilReady();\n\n printBanner({\n queue: this.options.queue,\n concurrency: worker.concurrency,\n redis: this.options.redis,\n mongo: this.options.mongo,\n recorderOpening,\n jobs: this.jobs,\n schedulers,\n });\n }\n\n private async openRecorder(\n jobResultsRecorder: JobResultsRecorder,\n worker: Worker,\n ): Promise<JobResultsRecorderOpening> {\n try {\n await jobResultsRecorder.open(worker);\n } catch (error) {\n this.sayJobResultsAreNotRecorded(error);\n return { opened: false, because: describeError(error) };\n }\n return { opened: true };\n }\n\n private sayJobResultsAreNotRecorded(error: unknown): void {\n this.logger.error(\n { err: error },\n `[ravenflow] the job results recorder could not start: the worker serves \"${this.options.queue}\", and its job results are not recorded.`,\n );\n }\n\n private takeJobs(worker: Worker): void {\n worker.run().catch((error: unknown) => {\n this.logger.error(\n { err: error },\n `[ravenflow] the worker serving \"${this.options.queue}\" stopped taking jobs.`,\n );\n });\n }\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport { RavenflowWorker } from \"./ravenflow-worker\";\nimport type { RavenflowWorkerOptions } from \"./types\";\n\nexport function createRavenflowWorker(\n config: RavenflowConfig,\n options: RavenflowWorkerOptions,\n): RavenflowWorker {\n return new RavenflowWorker(config, options);\n}\n","import { AnyJob } from \"@/job\";\nimport { LoggerOptions } from \"@/logger\";\n\nexport interface RavenflowConfig<TJobs extends string = string> {\n defaultQueue: string;\n jobs: Record<TJobs, AnyJob>;\n\n logger?: LoggerOptions;\n queuesRetention?: QueuesRetentionConfig;\n jobResultsRetentionHours?: number;\n aggregatedResultsRetentionHours?: number;\n}\n\nexport interface QueuesRetentionConfig {\n completedCount?: number;\n failedCount?: number;\n}\n\nexport function defineConfig<const T extends RavenflowConfig>(config: T): T {\n return config;\n}\n"]}
1
+ {"version":3,"sources":["../src/job/definition.ts","../src/job/any-job.ts","../src/job/continuation.ts","../src/job/deduplication-id.ts","../src/job/policies.ts","../src/config/validate-config/schemas/primitives.ts","../src/config/validate-config/schemas/pace.schema.ts","../src/spools/governor.ts","../src/config/validate-config/schemas/trigger.schema.ts","../src/config/validate-config/schemas/job.schema.ts","../src/config/constants.ts","../src/config/validate-config/schemas/config.schema.ts","../src/config/validate-config/shape-errors.ts","../src/config/validate-config/declared-jobs.ts","../src/config/validate-config/shared-spool-errors.ts","../src/config/validate-config/spool-pace-errors.ts","../src/config/validate-config/index.ts","../src/control-plane/control-key.ts","../src/control-plane/cache/control-cache.ts","../src/control-plane/control-plane.ts","../src/control-plane/redis-connection.ts","../src/control-plane/channel/control-channel.ts","../src/control-plane/levers.ts","../src/control-plane/store/live-controls.ts","../src/control-plane/store/rehydrate-controls.ts","../src/control-plane/store/control-store.ts","../src/control-plane/store/control-hash.ts","../src/control-plane/store/control-mirror.ts","../src/control-plane/init-control-plane.ts","../src/logger.ts","../src/mongo/connection.ts","../src/queues/declared-queues.ts","../src/queues/open-queues.ts","../src/queues/close-queues.ts","../src/queues/build-job-options.ts","../src/queues/link-id.ts","../src/spools/backlog.ts","../src/spools/spool-job-id.ts","../src/spools/item-runs.ts","../src/client/job-proxy/build-backlog.ts","../src/client/job-proxy/controls.ts","../src/client/job-proxy/deduplication.ts","../src/client/job-proxy/send.ts","../src/client/job-proxy/spool-ingest.ts","../src/client/job-proxy/init-job-proxies.ts","../src/client/create-ravenflow-client.ts","../src/worker/control-plane-reader.ts","../src/worker/log-bullmq-errors.ts","../src/worker/mongodb-deadline-on-close.ts","../src/worker/job-results-recorder/batch-writer.ts","../src/worker/job-results-recorder/job-results-collection.ts","../src/worker/job-router/execution-gate.ts","../src/worker/job-router/pace-gate.ts","../src/worker/job-router/execution-signal.ts","../src/worker/job-router/job-logger.ts","../src/worker/job-router/link-deduplication.ts","../src/worker/job-router/next-link.ts","../src/worker/job-router/run-link.ts","../src/worker/job-router/progress-marks.ts","../src/worker/job-router/trigger-gate.ts","../src/worker/job-router/route-by-name.ts","../src/worker/job-results-recorder/job-result-limits.ts","../src/worker/job-results-recorder/error-extraction.ts","../src/worker/job-results-recorder/storable-value.ts","../src/worker/job-results-recorder/job-result.ts","../src/worker/job-results-recorder/log-capture.ts","../src/worker/job-results-recorder/job-results-listener.ts","../src/worker/job-results-recorder/job-results-recorder.ts","../src/worker/internal-jobs/job-results-aggregator/aggregated-results-collection.ts","../src/worker/internal-jobs/job-results-aggregator/aggregate-job-results.ts","../src/worker/internal-jobs/job-results-aggregator/job-results-aggregator.ts","../src/worker/internal-jobs/spool-feeder/feed-spool.ts","../src/worker/internal-jobs/spool-feeder/item-removals.ts","../src/worker/internal-jobs/spool-feeder/stage.ts","../src/worker/internal-jobs/spool-feeder/ticks.ts","../src/worker/internal-jobs/spool-feeder/spool-feeder.ts","../src/worker/open-worker.ts","../src/worker/withdrawal/mongo-watch.ts","../src/worker/withdrawal/withdraw.ts","../src/worker/open-serving.ts","../src/worker/served-queue.ts","../src/describe-error.ts","../src/worker/banner.ts","../src/worker/schedulers.ts","../src/worker/serving.ts","../src/worker/create-ravenflow-worker.ts","../src/config/ravenflow-config.ts"],"names":["z","isObject","Redis","stored","pino","MongoClient","Queue","ObjectId","Job","release","MongoBulkWriteError","DelayedError","Worker","format","inspect","BSON","SECONDS_PER_HOUR","secondsOf","TICKS_KEPT","scheduleTicks","ONE_TICK_AT_A_TIME","MetricsTime","isRedisInstance"],"mappings":"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","file":"index.js","sourcesContent":["import type { Continuation } from \"./continuation\";\nimport type { JobContext } from \"./context\";\nimport type { BackoffPolicy, DeduplicatePolicy, PacePolicy } from \"./policies\";\nimport type { CronTrigger, SpoolTriggerDeclaration } from \"./trigger\";\nimport type { CronTriggerFor, TriggerFor } from \"./trigger-for\";\n\nexport interface JobDefinition<TPayload, TResult> {\n queue?: string;\n attempts?: number;\n backoff?: BackoffPolicy;\n trigger?: TriggerFor<TPayload>;\n deduplicate?: DeduplicatePolicy<TPayload>;\n pace?: PacePolicy;\n handler: JobHandler<TPayload, TResult>;\n}\n\nexport type JobHandler<TPayload, TResult> = (\n ctx: JobContext<TPayload>,\n) => Promise<TResult | Continuation<TPayload>>;\n\nexport type SpoolFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {\n trigger: SpoolTriggerDeclaration;\n pace: PacePolicy;\n};\n\nexport type ClockFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {\n trigger: CronTrigger;\n};\n\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinitionWith<SpoolTriggerDeclaration, TPayload, TResult> & { pace: PacePolicy },\n): SpoolFedJob<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinitionWith<CronTriggerFor<TPayload>, TPayload, TResult>,\n): ClockFedJob<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: UnspooledJobDefinition<TPayload, TResult>,\n): JobDefinition<TPayload, TResult>;\nexport function defineJob<TPayload, TResult>(\n definition: JobDefinition<TPayload, TResult>,\n): JobDefinition<TPayload, TResult> {\n return { ...definition };\n}\n\ntype JobDefinitionWith<TTrigger, TPayload, TResult> = Omit<\n JobDefinition<TPayload, TResult>,\n \"trigger\"\n> & { trigger: TTrigger };\n\ntype UnspooledJobDefinition<TPayload, TResult> = Omit<\n JobDefinition<TPayload, TResult>,\n \"trigger\"\n> & { trigger?: CronTriggerFor<TPayload> };\n","import type { JobContext } from \"./context\";\nimport type { BackoffPolicy, DeduplicatePolicy, PacePolicy } from \"./policies\";\nimport type { DeclaredTrigger, SpoolTrigger } from \"./trigger\";\n\nexport interface AnyJob {\n queue?: string;\n attempts?: number;\n backoff?: BackoffPolicy;\n trigger?: DeclaredTrigger;\n deduplicate?: DeduplicatePolicy<never>;\n pace?: PacePolicy;\n handler: (ctx: JobContext<never>) => Promise<unknown>;\n}\n\nexport interface AnySpoolFedJob extends AnyJob {\n trigger: DeclaredTrigger & { spool: SpoolTrigger };\n pace: PacePolicy;\n}\n\nexport function isSpoolFed(job: AnyJob): job is AnySpoolFedJob {\n return job.trigger?.spool !== undefined && job.pace !== undefined;\n}\n","const CONTINUATION = Symbol.for(\"ravenflow.continuation\");\n\nexport interface Continuation<TPayload> {\n readonly [CONTINUATION]: true;\n readonly params: TPayload;\n readonly delayMs?: number;\n readonly deduplicationId?: string;\n}\n\nexport interface ContinueOptions {\n delayMs?: number;\n deduplicationId?: string;\n}\n\nexport function continueWith<TPayload>(\n params: TPayload,\n options?: ContinueOptions,\n): Continuation<TPayload> {\n return {\n [CONTINUATION]: true,\n params,\n delayMs: options?.delayMs,\n deduplicationId: options?.deduplicationId,\n };\n}\n\nexport function isContinuation(value: unknown): value is Continuation<unknown> {\n return (\n isObject(value) && CONTINUATION in value && value[CONTINUATION] === true\n );\n}\n\nfunction isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n","export function namespacedDeduplicationId(\n jobName: string,\n deduplicationId: string,\n): string {\n return `${namespaceOf(jobName)}:${deduplicationId}`;\n}\n\nexport function deduplicationIdOf(\n jobName: string,\n namespacedId: string,\n): string {\n return namespacedId.slice(namespaceOf(jobName).length + 1);\n}\n\nfunction namespaceOf(jobName: string): string {\n return encodeURIComponent(jobName);\n}\n","export const MS_PER_PACE_UNIT = {\n perSecond: 1_000,\n perMinute: 60_000,\n perHour: 3_600_000,\n} as const;\n\nexport type PaceUnit = keyof typeof MS_PER_PACE_UNIT;\n\nexport const FASTEST_PACE_SPACING_MS = 1;\n\nexport const SLOWEST_PACE_SPACING_MS = 86_400_000;\n\nexport interface BackoffPolicy {\n type: \"fixed\" | \"exponential\";\n delayMs: number;\n jitter?: number;\n}\n\nexport type DeduplicatePolicy<TPayload> = true | ((params: TPayload) => string);\n\nexport type PacePolicy =\n | { perSecond: number; perMinute?: never; perHour?: never }\n | { perMinute: number; perSecond?: never; perHour?: never }\n | { perHour: number; perSecond?: never; perMinute?: never };\n\nexport function spacingMsOf(pace: PacePolicy): number {\n const { unit, releases } = releasesPerUnitOf(pace);\n return MS_PER_PACE_UNIT[unit] / releases;\n}\n\nexport function releasesWithin(ms: number, pace: PacePolicy): number {\n const { unit, releases } = releasesPerUnitOf(pace);\n return (ms * releases) / MS_PER_PACE_UNIT[unit];\n}\n\nfunction releasesPerUnitOf(pace: PacePolicy): {\n unit: PaceUnit;\n releases: number;\n} {\n if (pace.perSecond !== undefined) {\n return { unit: \"perSecond\", releases: pace.perSecond };\n }\n if (pace.perMinute !== undefined) {\n return { unit: \"perMinute\", releases: pace.perMinute };\n }\n return { unit: \"perHour\", releases: pace.perHour };\n}\n","import { z } from \"zod\";\n\nexport const wholeNumber = (min: number, error: string) =>\n z.number({ error }).int({ error }).min(min, { error });\n\nexport const numberBetween = (min: number, max: number, error: string) =>\n z.number({ error }).min(min, { error }).max(max, { error });\n\nexport const aFunction = z.custom<(...args: never[]) => unknown>(\n (value) => typeof value === \"function\",\n { error: \"must be a function.\" },\n);\n","import { z } from \"zod\";\nimport { FASTEST_PACE_SPACING_MS, MS_PER_PACE_UNIT, SLOWEST_PACE_SPACING_MS, type PaceUnit } from \"@/job\";\nimport { numberBetween } from \"./primitives\";\n\nconst ONE_UNIT = \"must declare exactly one of perSecond, perMinute or perHour.\";\n\nconst UNIT_NAMES: Record<PaceUnit, string> = { perSecond: \"second\", perMinute: \"minute\", perHour: \"hour\" };\n\nexport const paceSchema = z\n .strictObject({\n perSecond: releasesPer(\"perSecond\").optional(),\n perMinute: releasesPer(\"perMinute\").optional(),\n perHour: releasesPer(\"perHour\").optional(),\n })\n .refine(declaresOneUnit, { error: ONE_UNIT });\n\nfunction releasesPer(unit: PaceUnit) {\n const msPerUnit = MS_PER_PACE_UNIT[unit];\n const fastest = msPerUnit / FASTEST_PACE_SPACING_MS;\n return numberBetween(msPerUnit / SLOWEST_PACE_SPACING_MS, fastest, outOfRange(UNIT_NAMES[unit], fastest));\n}\n\nfunction outOfRange(unit: string, fastest: number): string {\n return `must be a number of releases per ${unit}, from one a day to ${fastest} — so 0.5 is one every two ${unit}s. Faster than one a millisecond cannot be spaced by Redis; slower than one a day is a pause, and there is a verb for that.`;\n}\n\nfunction declaresOneUnit(pace: Partial<Record<PaceUnit, number>>): boolean {\n const rates = [pace.perSecond, pace.perMinute, pace.perHour];\n return rates.filter((rate) => rate !== undefined).length === 1;\n}\n","import { releasesWithin, type PacePolicy, type SpoolTrigger } from \"@/job\";\n\nexport const DEFAULT_TICK_MS = 30_000;\n\nconst A_CLAIM_HOLDS_FOR_TICKS = 10;\n\nexport function tickMsOf(spool: SpoolTrigger): number {\n return spool.tickMs ?? DEFAULT_TICK_MS;\n}\n\nexport function claimHoldMsOf(spool: SpoolTrigger): number {\n return A_CLAIM_HOLDS_FOR_TICKS * tickMsOf(spool);\n}\n\nexport function inFlightCeilingOf(\n spool: SpoolTrigger,\n pace: PacePolicy,\n): number {\n return Math.ceil(releasesWithin(tickMsOf(spool), pace));\n}\n\nexport function roomUnderTheCeiling(\n spool: SpoolTrigger,\n pace: PacePolicy,\n inFlight: number,\n): number {\n return inFlightCeilingOf(spool, pace) - inFlight;\n}\n\nexport async function mayPull(spool: SpoolTrigger): Promise<boolean> {\n return (await spool.canPull?.()) ?? true;\n}\n","import { z } from \"zod\";\nimport { DEFAULT_TICK_MS } from \"@/spools/governor\";\nimport { aFunction, wholeNumber } from \"./primitives\";\n\nconst NO_NAME = \"must name the spool, whose backlog is rav:spool-backlog:<name>.\";\nconst COLON_IN_NAME =\n 'must not contain \":\" — it would break the job id of each item (spool:<name>:<_id>). Rename the spool.';\nconst NOT_A_TICK = `must be a whole number of milliseconds, one or more. Omit it to tick every ${DEFAULT_TICK_MS / 1_000} seconds.`;\nconst NOT_AN_EXPIRY = \"must be a whole number of milliseconds, one or more. Omit it to keep an item until it is released.\";\n\nexport const spoolNameSchema = z\n .string({ error: NO_NAME })\n .trim()\n .min(1, { error: NO_NAME })\n .refine((name) => !name.includes(\":\"), { error: COLON_IN_NAME });\n\nconst spoolSchema = z.strictObject({\n name: spoolNameSchema,\n tickMs: wholeNumber(1, NOT_A_TICK).optional(),\n canPull: aFunction.optional(),\n expireUnclaimedAfterMs: wholeNumber(1, NOT_AN_EXPIRY).optional(),\n});\n\nexport const triggerSchema = z.strictObject({\n cron: z.string({ error: \"must be a cron expression.\" }).optional(),\n spool: spoolSchema.optional(),\n});\n","import { z } from \"zod\";\nimport { paceSchema } from \"./pace.schema\";\nimport { aFunction, numberBetween } from \"./primitives\";\nimport { triggerSchema } from \"./trigger.schema\";\n\nconst NOT_A_JITTER =\n \"must be a number between 0 and 1: the share of its delay a retry may be brought forward by, so 0.2 retries between 80% and 100% of it.\";\nconst NOT_A_DEDUPLICATION =\n \"must be true or a function of the payload: true lets one run of the job be in flight at a time, a function one per id it returns. Omit it to deduplicate nothing.\";\n\nconst backoffSchema = z.strictObject({\n type: z.enum([\"fixed\", \"exponential\"], { error: \"must be 'fixed' or 'exponential'.\" }),\n delayMs: z.number({ error: \"must be a number of milliseconds.\" }),\n jitter: numberBetween(0, 1, NOT_A_JITTER).optional(),\n});\n\nconst deduplicateSchema = z.union([z.literal(true), aFunction], { error: NOT_A_DEDUPLICATION });\n\nexport const jobSchema = z.strictObject({\n queue: z.string({ error: \"must be a queue name.\" }).optional(),\n attempts: z.number({ error: \"must be a number.\" }).optional(),\n backoff: backoffSchema.optional(),\n trigger: triggerSchema.optional(),\n deduplicate: deduplicateSchema.optional(),\n pace: paceSchema.optional(),\n handler: aFunction,\n});\n","export const DEFAULT_COMPLETED_COUNT_RETENTION = 1000;\nexport const DEFAULT_FAILED_COUNT_RETENTION = 1000;\nexport const DEFAULT_JOB_RESULTS_RETENTION_HOURS = 14 * 24;\nexport const DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS = 90 * 24;\nexport const DEFAULT_GRACE_PERIOD_MS = 30_000;\n","import { z } from \"zod\";\nimport { jobSchema } from \"./job.schema\";\nimport {\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n} from \"../../constants\";\nimport { wholeNumber } from \"./primitives\";\n\nconst NOT_A_QUEUE = \"must be a queue name.\";\nconst NOT_A_JOB_COUNT = \"must be a whole number of jobs, zero or more. Omit it to use the default.\";\nconst NOT_A_LEVEL = \"must be one of trace, debug, info, warn, error, fatal.\";\nconst NOT_JOB_RESULTS_HOURS = notWholeHours(\"job results\", DEFAULT_JOB_RESULTS_RETENTION_HOURS);\nconst NOT_AGGREGATED_RESULTS_HOURS = notWholeHours(\"aggregated results\", DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS);\n\nconst loggerSchema = z.strictObject({\n level: z.enum([\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"], { error: NOT_A_LEVEL }).optional(),\n pretty: z.boolean({ error: \"must be true or false.\" }).optional(),\n});\n\nconst queuesRetentionSchema = z.strictObject({\n completedCount: wholeNumber(0, NOT_A_JOB_COUNT).optional(),\n failedCount: wholeNumber(0, NOT_A_JOB_COUNT).optional(),\n});\n\nexport const configSchema = z.strictObject({\n defaultQueue: z.string({ error: NOT_A_QUEUE }).min(1, { error: NOT_A_QUEUE }),\n jobs: z.record(z.string(), jobSchema, { error: \"must map each job's name to its declaration.\" }),\n logger: loggerSchema.optional(),\n queuesRetention: queuesRetentionSchema.optional(),\n jobResultsRetentionHours: wholeNumber(1, NOT_JOB_RESULTS_HOURS).optional(),\n aggregatedResultsRetentionHours: wholeNumber(1, NOT_AGGREGATED_RESULTS_HOURS).optional(),\n});\n\nfunction notWholeHours(kept: string, defaultHours: number): string {\n return `must be a whole number of hours, one or more. Omit it to keep ${kept} ${defaultHours / 24} days.`;\n}\n","import type { z } from \"zod\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\nimport { configSchema } from \"./schemas\";\n\nexport function shapeErrors(config: RavenflowConfig): string[] {\n const parsed = configSchema.safeParse(config);\n return parsed.success ? [] : parsed.error.issues.flatMap(describeIssue);\n}\n\nfunction describeIssue(issue: z.core.$ZodIssue): string[] {\n const path = issue.path.map(String);\n const inJob = path[0] === \"jobs\" && path.length > 1;\n const subject = inJob ? `\"${path[1]}\"` : \"config\";\n const field = inJob ? path.slice(2) : path;\n\n if (issue.code === \"unrecognized_keys\") {\n return issue.keys.map((key) => unknownKey(subject, [...field, key]));\n }\n return [[subject, field.join(\".\"), issue.message].filter(Boolean).join(\" \")];\n}\n\nfunction unknownKey(subject: string, field: string[]): string {\n return `${subject} ${field.join(\".\")} is not a key Ravenflow reads — check its spelling.`;\n}\n","import type { AnyJob } from \"@/job\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\n\nexport function declaredJobs(config: RavenflowConfig): Array<[string, AnyJob]> {\n const jobs: unknown = config.jobs;\n if (!isObject(jobs)) return [];\n return Object.entries(jobs as Record<string, AnyJob>).filter(([, job]) => isObject(job));\n}\n\nfunction isObject(value: unknown): value is object {\n return value !== null && typeof value === \"object\";\n}\n","import type { RavenflowConfig } from \"../ravenflow-config\";\nimport { declaredJobs } from \"./declared-jobs\";\nimport { spoolNameSchema } from \"./schemas\";\n\nexport function sharedSpoolErrors(config: RavenflowConfig): string[] {\n const ownerBySpool = new Map<string, string>();\n const errors: string[] = [];\n\n for (const [name, spoolName] of spoolNameOfEachJob(config)) {\n const owner = ownerBySpool.get(spoolName);\n if (owner !== undefined) {\n errors.push(sharedSpool(name, owner, spoolName));\n continue;\n }\n ownerBySpool.set(spoolName, name);\n }\n return errors;\n}\n\nfunction spoolNameOfEachJob(config: RavenflowConfig): Array<[string, string]> {\n return declaredJobs(config).flatMap(([name, job]): Array<[string, string]> => {\n const parsed = spoolNameSchema.safeParse(job.trigger?.spool?.name);\n return parsed.success ? [[name, parsed.data]] : [];\n });\n}\n\nfunction sharedSpool(name: string, owner: string, spoolName: string): string {\n return `\"${name}\" and \"${owner}\" are both fed by the spool \"${spoolName}\". Two jobs over one backlog would claim each other's items.`;\n}\n","import type { AnyJob } from \"@/job\";\nimport type { RavenflowConfig } from \"../ravenflow-config\";\nimport { declaredJobs } from \"./declared-jobs\";\n\nexport function spoolPaceErrors(config: RavenflowConfig): string[] {\n return declaredJobs(config)\n .filter(([, job]) => isSpoolFedWithoutAPace(job))\n .map(([name]) => `\"${name}\" pace is required: a spool drains at its job's pace.`);\n}\n\nfunction isSpoolFedWithoutAPace(job: AnyJob): boolean {\n return job.trigger?.spool !== undefined && job.pace === undefined;\n}\n","import type { RavenflowConfig } from \"../ravenflow-config\";\nimport { shapeErrors } from \"./shape-errors\";\nimport { sharedSpoolErrors } from \"./shared-spool-errors\";\nimport { spoolPaceErrors } from \"./spool-pace-errors\";\n\nexport function validateConfig(config: RavenflowConfig): void {\n throwIfAny([\n ...shapeErrors(config),\n ...spoolPaceErrors(config),\n ...sharedSpoolErrors(config),\n ]);\n}\n\nfunction throwIfAny(errors: string[]): void {\n if (errors.length === 0) return;\n throw new Error(`[ravenflow] Config validation failed:\\n - ${errors.join(\"\\n - \")}`);\n}\n","const JOB_PREFIX = \"job:\";\n\nexport type ControlKey = `job:${string}`;\n\nexport const CONTROL_KEY_MAX_LENGTH = 512;\n\nexport function controlKey(jobName: string): ControlKey {\n return `${JOB_PREFIX}${jobName}`;\n}\n\nexport function isControlKey(raw: unknown): raw is ControlKey {\n if (typeof raw !== \"string\" || raw.length > CONTROL_KEY_MAX_LENGTH) return false;\n return raw.startsWith(JOB_PREFIX) && raw.length > JOB_PREFIX.length;\n}\n\nexport function jobNameOf(key: ControlKey): string {\n return key.slice(JOB_PREFIX.length);\n}\n\nexport function validateControlName(name: string, caller: string): void {\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new Error(`${caller}: name must be a non-empty string`);\n }\n\n if (name.includes(\".\") || name.includes(\"$\")) {\n throw new Error(\n `${caller}: name cannot contain '.' or '$' (Mongo-reserved characters)`,\n );\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey, type ControlKey } from \"../control-key\";\nimport type { JobControls } from \"../levers\";\nimport type { ControlReads } from \"../types\";\n\nexport const CONTROL_CACHE_TTL_MS = 15_000;\n\nexport interface InvalidationSource {\n subscribe(onInvalidate: (key: ControlKey) => void): Promise<void>;\n}\n\nexport class ControlCache implements ControlReads {\n private readonly entries = new Map<\n ControlKey,\n {\n controls: JobControls;\n expiresAt: number;\n }\n >();\n private readonly inFlight = new Map<ControlKey, Promise<JobControls>>();\n private subscription: Promise<void> | null = null;\n\n constructor(\n private readonly parts: {\n source: ControlReads;\n invalidations: InvalidationSource;\n logger: Logger;\n },\n ) {}\n\n async read(jobName: string): Promise<JobControls> {\n const key = controlKey(jobName);\n const cached = this.entries.get(key);\n if (cached !== undefined && cached.expiresAt > Date.now()) {\n return cached.controls;\n }\n\n this.subscribeOnce();\n\n const reading = this.inFlight.get(key);\n if (reading !== undefined) return await reading;\n\n return await this.startRead(key, jobName);\n }\n\n invalidate(key: ControlKey): void {\n this.entries.delete(key);\n this.inFlight.delete(key);\n }\n\n clear(): void {\n this.entries.clear();\n this.inFlight.clear();\n }\n\n private startRead(key: ControlKey, jobName: string): Promise<JobControls> {\n const reading: Promise<JobControls> = this.parts.source.read(jobName).then(\n (controls) => {\n if (this.inFlight.get(key) === reading) this.keep(key, controls);\n return controls;\n },\n (err: unknown) => {\n if (this.inFlight.get(key) === reading) this.inFlight.delete(key);\n throw err;\n },\n );\n\n this.inFlight.set(key, reading);\n return reading;\n }\n\n private keep(key: ControlKey, controls: JobControls): void {\n this.entries.set(key, {\n controls,\n expiresAt: Date.now() + CONTROL_CACHE_TTL_MS,\n });\n this.inFlight.delete(key);\n }\n\n private subscribeOnce(): void {\n if (this.subscription) return;\n\n this.subscription = this.parts.invalidations\n .subscribe((key) => this.invalidate(key))\n .catch((err: unknown) => {\n this.parts.logger.warn(\n { err },\n \"[control] invalidation subscribe failed — changes arrive on the cache TTL instead\",\n );\n });\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport { ControlCache } from \"./cache\";\nimport type { ControlChannel } from \"./channel\";\nimport { controlKey } from \"./control-key\";\nimport type { JobControls } from \"./levers\";\nimport type { ControlStore } from \"./store\";\nimport type { JobControlPlane } from \"./types\";\n\nexport class ControlPlane implements JobControlPlane {\n private readonly cache: ControlCache;\n\n constructor(\n private readonly parts: {\n store: ControlStore;\n channel: ControlChannel;\n logger: Logger;\n },\n ) {\n this.cache = new ControlCache({\n source: parts.store,\n invalidations: parts.channel,\n logger: parts.logger,\n });\n }\n\n async read(jobName: string): Promise<JobControls> {\n return await this.cache.read(jobName);\n }\n\n async write(jobName: string, patch: Partial<JobControls>): Promise<void> {\n await this.parts.store.write(jobName, patch);\n this.cache.invalidate(controlKey(jobName));\n }\n\n async rehydrate(): Promise<void> {\n try {\n await this.parts.store.rehydrate();\n this.cache.clear();\n } catch (err) {\n this.parts.logger.error(\n { err },\n \"[control] rehydration failed — controls set before this boot may read as unset until they are written again\",\n );\n }\n }\n\n async close(): Promise<void> {\n await this.closeQuietly(\n () => this.parts.store.close(),\n \"[control] control store close failed\",\n );\n await this.closeQuietly(\n () => this.parts.channel.close(),\n \"[control] control channel close failed\",\n );\n }\n\n private async closeQuietly(\n close: () => Promise<void>,\n failure: string,\n ): Promise<void> {\n try {\n await close();\n } catch (err) {\n this.parts.logger.warn({ err }, failure);\n }\n }\n}\n","import { Redis, type Cluster } from \"ioredis\";\nimport type {\n ConnectionOptions,\n RedisOptions as BullMQRedisOptions,\n} from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nexport type RavenflowConnection = Redis | Cluster;\n\nexport type ConnectionRole = \"publisher\" | \"subscriber\" | \"store\";\n\nexport function openRavenflowConnection(\n connection: ConnectionOptions,\n role: ConnectionRole,\n logger: Logger,\n): RavenflowConnection {\n const opened = duplicateOrBuild(connection);\n opened.on(\"error\", (err: Error) => {\n logger.warn(\n { err, role },\n \"[ravenflow] redis connection error — ioredis reconnects, a command in flight fails\",\n );\n });\n return opened;\n}\n\nfunction duplicateOrBuild(connection: ConnectionOptions): RavenflowConnection {\n const candidate = connection as Partial<Redis>;\n if (typeof candidate.duplicate === \"function\") {\n return (connection as Redis).duplicate();\n }\n\n const { url, ...rest } = connection as BullMQRedisOptions;\n return url ? new Redis(url, rest) : new Redis(rest);\n}\n","import type { ConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport {\n openRavenflowConnection,\n type RavenflowConnection,\n} from \"../redis-connection\";\n\nimport { isControlKey, type ControlKey } from \"../control-key\";\n\nexport const CONTROL_INVALIDATION_CHANNEL = \"rav:controls:invalidate\";\n\nexport interface ControlPublisher {\n publish(key: ControlKey): Promise<void>;\n}\n\nexport class ControlChannel implements ControlPublisher {\n private publisher: RavenflowConnection | null = null;\n private subscriber: RavenflowConnection | null = null;\n\n constructor(\n private readonly connection: ConnectionOptions,\n private readonly logger: Logger,\n ) {}\n\n async publish(key: ControlKey): Promise<void> {\n this.publisher ??= this.open(\"publisher\");\n await this.publisher.publish(CONTROL_INVALIDATION_CHANNEL, key);\n }\n\n async subscribe(onInvalidate: (key: ControlKey) => void): Promise<void> {\n if (this.subscriber) {\n throw new Error(\"[ravenflow] ControlChannel is already subscribed\");\n }\n\n const subscriber = this.open(\"subscriber\");\n this.subscriber = subscriber;\n subscriber.on(\"message\", (channel: string, message: string) => {\n if (channel === CONTROL_INVALIDATION_CHANNEL) {\n this.deliver(message, onInvalidate);\n }\n });\n\n try {\n await this.listenOn(subscriber);\n } catch (err) {\n if (this.subscriber === subscriber) this.subscriber = null;\n throw err;\n }\n }\n\n async close(): Promise<void> {\n const open = [this.publisher, this.subscriber].filter(\n (connection) => connection !== null,\n );\n this.publisher = null;\n this.subscriber = null;\n\n await Promise.all(open.map(leave));\n }\n\n private deliver(\n message: string,\n onInvalidate: (key: ControlKey) => void,\n ): void {\n if (!isControlKey(message)) {\n this.logger.warn(\n { channel: CONTROL_INVALIDATION_CHANNEL, length: message.length },\n \"[control] invalidation message is not a control key — ignored\",\n );\n return;\n }\n\n onInvalidate(message);\n }\n\n private async listenOn(subscriber: RavenflowConnection): Promise<void> {\n try {\n await subscriber.subscribe(CONTROL_INVALIDATION_CHANNEL);\n } catch (err) {\n subscriber.disconnect();\n throw err;\n }\n }\n\n private open(role: \"publisher\" | \"subscriber\"): RavenflowConnection {\n return openRavenflowConnection(this.connection, role, this.logger);\n }\n}\n\nasync function leave(connection: RavenflowConnection): Promise<void> {\n try {\n await connection.quit();\n } catch {\n connection.disconnect();\n }\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { ControlKey } from \"./control-key\";\n\nexport const LEVERS = [\"executionPaused\", \"triggerPaused\", \"ingestPaused\"] as const;\n\nexport type Lever = (typeof LEVERS)[number];\n\nexport type JobControls = Record<Lever, boolean>;\n\nexport const JOB_CONTROLS_OPEN: JobControls = {\n executionPaused: false,\n triggerPaused: false,\n ingestPaused: false,\n};\n\nexport function decodeLever(\n raw: string | undefined,\n key: ControlKey,\n logger: Logger,\n): boolean | undefined {\n if (raw === undefined) return undefined;\n\n let stored: unknown;\n try {\n stored = JSON.parse(raw);\n } catch (err) {\n logger.warn(\n { err, key },\n \"[control] stored control is not readable — treating it as unset\",\n );\n return undefined;\n }\n\n if (typeof stored === \"boolean\") return stored;\n\n logger.warn(\n { key, type: typeof stored },\n \"[control] stored control is not a boolean — treating it as unset\",\n );\n return undefined;\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey } from \"../control-key\";\nimport { decodeLever, JOB_CONTROLS_OPEN, type JobControls } from \"../levers\";\nimport type { StoredLever } from \"./control-hash\";\n\nexport type LiveControls = Map<string, JobControls>;\n\nexport function liveControls(\n stored: StoredLever[],\n logger: Logger,\n): LiveControls {\n const live: LiveControls = new Map();\n\n for (const held of stored) {\n const pulled = decodeLever(held.value, controlKey(held.jobName), logger);\n if (pulled === undefined) continue;\n\n const controls = live.get(held.jobName) ?? { ...JOB_CONTROLS_OPEN };\n controls[held.lever] = pulled;\n live.set(held.jobName, controls);\n }\n\n return live;\n}\n","import type { Logger } from \"@/logger\";\n\nimport { controlKey } from \"../control-key\";\nimport { LEVERS } from \"../levers\";\nimport type { ControlHash, LeverEntry } from \"./control-hash\";\nimport type { ControlMirror, MirroredControls } from \"./control-mirror\";\n\nexport const CONTROL_REHYDRATE_MAX_ENTRIES = 10_000;\n\nexport interface RehydrationParts {\n hash: ControlHash;\n mirror: ControlMirror;\n logger: Logger;\n}\n\nexport interface RehydrationReport {\n restored: number;\n alreadyLive: number;\n truncated: boolean;\n}\n\nexport async function rehydrateControls(\n parts: RehydrationParts,\n): Promise<RehydrationReport> {\n const levers = (await parts.mirror.listAll()).flatMap(pulledLevers);\n const report = await restoreMissing(parts.hash, levers);\n\n if (report.truncated) reportTruncation(parts.logger, levers.length);\n\n return report;\n}\n\nfunction pulledLevers(mirrored: MirroredControls): LeverEntry[] {\n const key = controlKey(mirrored._id);\n\n return LEVERS.filter((lever) => mirrored[lever] === true).map(\n (lever): LeverEntry => ({ key, lever, value: JSON.stringify(true) }),\n );\n}\n\nasync function restoreMissing(\n hash: ControlHash,\n levers: LeverEntry[],\n): Promise<RehydrationReport> {\n let restored = 0;\n let alreadyLive = 0;\n\n for (const lever of levers.slice(0, CONTROL_REHYDRATE_MAX_ENTRIES)) {\n if (await hash.writeIfAbsent(lever)) restored++;\n else alreadyLive++;\n }\n\n return {\n restored,\n alreadyLive,\n truncated: levers.length > CONTROL_REHYDRATE_MAX_ENTRIES,\n };\n}\n\nfunction reportTruncation(logger: Logger, held: number): void {\n logger.error(\n {\n fields: held,\n cap: CONTROL_REHYDRATE_MAX_ENTRIES,\n skipped: held - CONTROL_REHYDRATE_MAX_ENTRIES,\n },\n \"[control] the mirror holds more controls than rehydration will restore — the controls past the cap read as open until they are set again\",\n );\n}\n","import type { Logger } from \"@/logger\";\n\nimport type { ControlPublisher } from \"../channel\";\nimport {\n controlKey,\n validateControlName,\n type ControlKey,\n} from \"../control-key\";\nimport { decodeLever, LEVERS, type JobControls } from \"../levers\";\nimport type { JobControlPlane } from \"../types\";\nimport type { ControlHash } from \"./control-hash\";\nimport type { ControlMirror } from \"./control-mirror\";\nimport { liveControls, type LiveControls } from \"./live-controls\";\nimport {\n rehydrateControls,\n type RehydrationReport,\n} from \"./rehydrate-controls\";\n\nexport interface ControlStoreParts {\n hash: ControlHash;\n publisher: ControlPublisher;\n mirror: ControlMirror;\n logger: Logger;\n}\n\nexport class ControlStore implements JobControlPlane {\n constructor(private readonly parts: ControlStoreParts) {}\n\n async read(jobName: string): Promise<JobControls> {\n const key = controlKey(jobName);\n const stored = await this.parts.hash.readLevers(key);\n\n return {\n executionPaused: this.isPulled(stored.get(\"executionPaused\"), key),\n triggerPaused: this.isPulled(stored.get(\"triggerPaused\"), key),\n ingestPaused: this.isPulled(stored.get(\"ingestPaused\"), key),\n };\n }\n\n async write(jobName: string, patch: Partial<JobControls>): Promise<void> {\n validateControlName(jobName, \"ControlStore.write\");\n refuseNonBooleanLevers(patch);\n const key = controlKey(jobName);\n\n await this.writeLevers(key, patch);\n await this.announce(key);\n await this.writeMirror(jobName, patch);\n }\n\n async readAll(): Promise<LiveControls> {\n return liveControls(\n await this.parts.hash.readEveryLever(),\n this.parts.logger,\n );\n }\n\n async rehydrate(): Promise<RehydrationReport> {\n return await rehydrateControls({\n hash: this.parts.hash,\n mirror: this.parts.mirror,\n logger: this.parts.logger,\n });\n }\n\n async close(): Promise<void> {\n await this.parts.hash.close();\n }\n\n private isPulled(raw: string | undefined, key: ControlKey): boolean {\n return decodeLever(raw, key, this.parts.logger) ?? false;\n }\n\n private async writeLevers(\n key: ControlKey,\n patch: Partial<JobControls>,\n ): Promise<void> {\n for (const lever of LEVERS) {\n const pulled = patch[lever];\n if (pulled === undefined) continue;\n\n await this.parts.hash.write({\n key,\n lever,\n value: JSON.stringify(pulled),\n });\n }\n }\n\n private async announce(key: ControlKey): Promise<void> {\n try {\n await this.parts.publisher.publish(key);\n } catch (err) {\n this.parts.logger.warn(\n { err, key },\n \"[control] invalidation publish failed — workers pick this up on the cache TTL instead\",\n );\n }\n }\n\n private async writeMirror(\n jobName: string,\n patch: Partial<JobControls>,\n ): Promise<void> {\n try {\n await this.parts.mirror.mirrorJobControls(jobName, patch);\n } catch (err) {\n this.parts.logger.error(\n { err, jobName, patch },\n \"[control] mirror write failed — the change is live but will not survive a Redis flush until the next successful write\",\n );\n }\n }\n}\n\nfunction refuseNonBooleanLevers(patch: Partial<JobControls>): void {\n for (const lever of LEVERS) {\n const pulled = patch[lever];\n if (pulled === undefined || typeof pulled === \"boolean\") continue;\n\n throw new Error(`ControlStore.write: ${lever} must be a boolean`);\n }\n}\n","import type { ConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport { openRavenflowConnection } from \"../redis-connection\";\n\nimport { isControlKey, jobNameOf, type ControlKey } from \"../control-key\";\nimport { LEVERS, type Lever } from \"../levers\";\n\nexport const CONTROL_HASH_KEY = \"rav:controls\";\n\nexport interface LeverEntry {\n key: ControlKey;\n lever: Lever;\n value: string;\n}\n\nexport interface StoredLever {\n jobName: string;\n lever: Lever;\n value: string;\n}\n\ninterface HashConnection {\n hgetall(key: string): Promise<Record<string, string>>;\n hmget(key: string, ...fields: string[]): Promise<Array<string | null>>;\n hset(key: string, field: string, value: string): Promise<number>;\n hsetnx(key: string, field: string, value: string): Promise<number>;\n quit(): Promise<unknown>;\n disconnect(): void;\n}\n\nexport class ControlHash {\n private connection: HashConnection | null = null;\n\n constructor(\n private readonly options: ConnectionOptions,\n private readonly logger: Logger,\n ) {}\n\n async readLevers(key: ControlKey): Promise<Map<Lever, string>> {\n const stored = await this.redis.hmget(\n CONTROL_HASH_KEY,\n ...LEVERS.map((lever) => controlField(key, lever)),\n );\n\n const pulled = new Map<Lever, string>();\n LEVERS.forEach((lever, index) => {\n const raw = stored[index];\n if (raw !== null && raw !== undefined) pulled.set(lever, raw);\n });\n return pulled;\n }\n\n async readEveryLever(): Promise<StoredLever[]> {\n return storedLevers(await this.redis.hgetall(CONTROL_HASH_KEY));\n }\n\n async write(entry: LeverEntry): Promise<void> {\n await this.redis.hset(\n CONTROL_HASH_KEY,\n controlField(entry.key, entry.lever),\n entry.value,\n );\n }\n\n async writeIfAbsent(entry: LeverEntry): Promise<boolean> {\n const written = await this.redis.hsetnx(\n CONTROL_HASH_KEY,\n controlField(entry.key, entry.lever),\n entry.value,\n );\n return written === 1;\n }\n\n async close(): Promise<void> {\n const open = this.connection;\n this.connection = null;\n if (!open) return;\n\n try {\n await open.quit();\n } catch {\n open.disconnect();\n }\n }\n\n private get redis(): HashConnection {\n this.connection ??= openRavenflowConnection(\n this.options,\n \"store\",\n this.logger,\n ) as HashConnection;\n return this.connection;\n }\n}\n\nexport function controlField(key: ControlKey, lever: Lever): string {\n return `${key}#${lever}`;\n}\n\nfunction storedLevers(fields: Record<string, string>): StoredLever[] {\n return Object.entries(fields).flatMap(([field, value]): StoredLever[] => {\n const held = leverOf(field);\n return held === undefined ? [] : [{ ...held, value }];\n });\n}\n\nfunction leverOf(field: string): { jobName: string; lever: Lever } | undefined {\n for (const lever of LEVERS) {\n const suffix = `#${lever}`;\n if (!field.endsWith(suffix)) continue;\n\n const key = field.slice(0, -suffix.length);\n if (isControlKey(key)) return { jobName: jobNameOf(key), lever };\n }\n return undefined;\n}\n","import type { Collection } from \"mongodb\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nimport type { JobControls } from \"../levers\";\n\nconst CONTROL_MIRROR_COLLECTION = \"rav:job-controls\";\n\nexport interface MirroredControls extends Partial<JobControls> {\n _id: string;\n updatedAt: Date;\n}\n\nexport interface ControlMirror {\n mirrorJobControls(\n jobName: string,\n patch: Partial<JobControls>,\n ): Promise<void>;\n listAll(): Promise<MirroredControls[]>;\n}\n\nexport function controlMirror(connection: MongoConnection): ControlMirror {\n const mirrorCollection = async (): Promise<Collection<MirroredControls>> => {\n const db = await connection.connect();\n return db.collection<MirroredControls>(CONTROL_MIRROR_COLLECTION);\n };\n\n return {\n mirrorJobControls: async (jobName, patch) => {\n const collection = await mirrorCollection();\n await collection.updateOne(\n { _id: jobName },\n { $set: { ...patch, updatedAt: new Date() } },\n { upsert: true },\n );\n },\n listAll: async () => (await mirrorCollection()).find().toArray(),\n };\n}\n","import type { ConnectionOptions as RedisConnectionOptions } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nimport { ControlPlane } from \"./control-plane\";\nimport { ControlChannel } from \"./channel\";\nimport { ControlHash, ControlStore, controlMirror } from \"./store\";\n\nexport function initControlPlane(runtime: {\n redis: RedisConnectionOptions;\n mongo: MongoConnection;\n logger: Logger;\n}): ControlPlane {\n const channel = new ControlChannel(runtime.redis, runtime.logger);\n const store = new ControlStore({\n hash: new ControlHash(runtime.redis, runtime.logger),\n publisher: channel,\n mirror: controlMirror(runtime.mongo),\n logger: runtime.logger,\n });\n\n return new ControlPlane({ store, channel, logger: runtime.logger });\n}\n","import pino from \"pino\";\n\nexport type Logger = pino.Logger;\n\nexport interface LoggerOptions {\n level?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n pretty?: boolean;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const isDev = process.env.NODE_ENV !== \"production\";\n const usePretty = options.pretty ?? isDev;\n\n return pino({\n level: options.level ?? (isDev ? \"debug\" : \"info\"),\n transport: usePretty\n ? {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"HH:MM:ss\",\n ignore: \"pid,hostname,job\",\n messageFormat: \"{if job}({job}) {end}{msg}\",\n },\n }\n : undefined,\n });\n}\n","import { MongoClient, type Db } from \"mongodb\";\n\nexport class MongoConnection {\n private client: MongoClient | null = null;\n private database: Db | null = null;\n private connecting: Promise<Db> | null = null;\n\n constructor(private readonly uri: string) {}\n\n async connect(): Promise<Db> {\n if (this.database) return this.database;\n this.connecting ??= this.openTheDatabase().catch((error: unknown) =>\n this.forgetTheAttempt(error),\n );\n return this.connecting;\n }\n\n async close(): Promise<void> {\n const closing = this.client;\n this.client = null;\n this.database = null;\n this.connecting = null;\n await closing?.close();\n }\n\n private async openTheDatabase(): Promise<Db> {\n const opened = new MongoClient(this.uri);\n await opened.connect();\n this.client = opened;\n this.database = opened.db();\n return this.database;\n }\n\n private forgetTheAttempt(error: unknown): never {\n this.connecting = null;\n throw error;\n }\n}\n","import type { RavenflowConfig } from \"@/config/ravenflow-config\";\nimport type { AnyJob } from \"@/job\";\n\nexport function declaredQueueNames(config: RavenflowConfig): string[] {\n const queueOfEachJob = Object.values(config.jobs).map((job) =>\n queueOf(job, config),\n );\n return [...new Set([config.defaultQueue, ...queueOfEachJob])];\n}\n\nexport function jobsDeclaredOn(\n queue: string,\n config: RavenflowConfig,\n): Record<string, AnyJob> {\n return Object.fromEntries(\n Object.entries(config.jobs).filter(\n ([, job]) => queueOf(job, config) === queue,\n ),\n );\n}\n\nfunction queueOf(job: AnyJob, config: RavenflowConfig): string {\n return job.queue ?? config.defaultQueue;\n}\n","import { Queue, type ConnectionOptions, type DefaultJobOptions } from \"bullmq\";\nimport type {\n RavenflowConfig,\n QueuesRetentionConfig,\n} from \"@/config/ravenflow-config\";\n\nimport {\n DEFAULT_COMPLETED_COUNT_RETENTION,\n DEFAULT_FAILED_COUNT_RETENTION,\n} from \"@/config/constants\";\n\nimport { declaredQueueNames } from \"./declared-queues\";\n\nexport type QueuesByName = Record<string, Queue>;\n\nexport interface QueueSettings {\n connection: ConnectionOptions;\n retention?: QueuesRetentionConfig;\n}\n\nexport function openQueues(\n config: RavenflowConfig,\n connection: ConnectionOptions,\n): QueuesByName {\n const settings = { connection, retention: config.queuesRetention };\n return Object.fromEntries(\n declaredQueueNames(config).map((name): [string, Queue] => [\n name,\n openQueue(name, settings),\n ]),\n );\n}\n\nexport function openQueue(name: string, settings: QueueSettings): Queue {\n return new Queue(name, {\n connection: settings.connection,\n defaultJobOptions: defaultJobOptionsFor(settings.retention),\n });\n}\n\nfunction defaultJobOptionsFor(\n retention: QueuesRetentionConfig = {},\n): DefaultJobOptions {\n return {\n removeOnComplete: {\n count: retention.completedCount ?? DEFAULT_COMPLETED_COUNT_RETENTION,\n },\n removeOnFail: {\n count: retention.failedCount ?? DEFAULT_FAILED_COUNT_RETENTION,\n },\n };\n}\n","import type { QueuesByName } from \"./open-queues\";\n\nexport async function closeQueues(queues: QueuesByName): Promise<void> {\n await Promise.all(Object.values(queues).map((queue) => queue.close()));\n}\n","import type { BackoffOptions, JobsOptions } from \"bullmq\";\nimport type { AnyJob, BackoffPolicy } from \"@/job\";\n\nexport function buildJobOptions(\n job: Pick<AnyJob, \"attempts\" | \"backoff\">,\n): JobsOptions {\n const options: JobsOptions = {};\n if (job.attempts !== undefined) options.attempts = job.attempts;\n if (job.backoff !== undefined) options.backoff = backoffOptions(job.backoff);\n\n return options;\n}\n\nfunction backoffOptions(backoff: BackoffPolicy): BackoffOptions {\n return {\n type: backoff.type,\n delay: backoff.delayMs,\n jitter: backoff.jitter,\n };\n}\n","const LINK_SEPARATOR = \".\";\n\nconst A_NUMBERED_LINK = /^(.+)\\.([1-9]\\d*)$/;\n\nexport interface LinkOfARun {\n runId: string;\n link: number;\n}\n\nexport function nextLinkIdOf(linkId: string): string {\n const { runId, link } = linkOfItsRun(linkId);\n return linkIdOf({ runId, link: link + 1 });\n}\n\nexport function linkIdOf({ runId, link }: LinkOfARun): string {\n if (link === 0) return runId;\n return `${asACustomJobId(runId)}${LINK_SEPARATOR}${link}`;\n}\n\nexport function linkOfItsRun(linkId: string): LinkOfARun {\n const numbered = A_NUMBERED_LINK.exec(linkId);\n if (numbered === null) return { runId: linkId, link: 0 };\n return { runId: numbered[1], link: Number(numbered[2]) };\n}\n\nfunction asACustomJobId(runId: string): string {\n if (holdsColonsBullmqRefuses(runId)) return encodeURIComponent(runId);\n return runId;\n}\n\nfunction holdsColonsBullmqRefuses(id: string): boolean {\n const parts = id.split(\":\").length;\n return parts !== 1 && parts !== 3;\n}\n","import { ObjectId, type Collection, type Filter, type WithId } from \"mongodb\";\nimport type { MongoConnection } from \"@/mongo/connection\";\n\nexport type SpoolItem = Record<string, unknown>;\n\nexport interface BacklogEntry {\n item: SpoolItem;\n claimedAt?: Date;\n}\n\nexport type StoredEntry = WithId<BacklogEntry>;\n\nexport interface SpoolPurgeReport {\n dropped: number;\n inFlight: number;\n}\n\nconst BACKLOG_COLLECTION_PREFIX = \"rav:spool-backlog:\";\n\nconst NEVER_CLAIMED: Filter<BacklogEntry> = { claimedAt: { $exists: false } };\n\nconst CLAIMED: Filter<BacklogEntry> = { claimedAt: { $type: \"date\" } };\n\nconst CLAIM_INDEX = { claimedAt: 1, _id: 1 } as const;\n\nconst OLDEST_FIRST = { _id: 1 } as const;\n\nconst MS_PER_SECOND = 1_000;\n\nexport class Backlog {\n constructor(\n readonly spoolName: string,\n private readonly connection: MongoConnection,\n ) {}\n\n async push(item: SpoolItem): Promise<string> {\n const backlog = await this.collection();\n const { insertedId } = await backlog.insertOne({ item });\n return insertedId.toHexString();\n }\n\n async pushMany(items: SpoolItem[]): Promise<string[]> {\n if (items.length === 0) return [];\n const backlog = await this.collection();\n const { insertedIds } = await backlog.insertMany(\n items.map((item) => ({ item })),\n );\n return items.map((_, position) => insertedIds[position].toHexString());\n }\n\n async purge(): Promise<SpoolPurgeReport> {\n const backlog = await this.collection();\n const { deletedCount } = await backlog.deleteMany(NEVER_CLAIMED);\n return {\n dropped: deletedCount,\n inFlight: await backlog.countDocuments(CLAIMED),\n };\n }\n\n async indexForTheClaim(): Promise<void> {\n const backlog = await this.collection();\n await backlog.createIndex(CLAIM_INDEX);\n }\n\n async countInFlight(): Promise<number> {\n const backlog = await this.collection();\n return backlog.countDocuments(CLAIMED);\n }\n\n async expireUnclaimedPushedBefore(pushedBefore: Date): Promise<number> {\n const backlog = await this.collection();\n const { deletedCount } = await backlog.deleteMany({\n ...NEVER_CLAIMED,\n _id: { $lt: ObjectId.createFromTime(secondsOf(pushedBefore)) },\n });\n return deletedCount;\n }\n\n async reclaimStaleClaims(\n claimedBefore: Date,\n now: Date,\n ): Promise<StoredEntry[]> {\n const staleClaim: Filter<BacklogEntry> = {\n claimedAt: { $lte: claimedBefore },\n };\n const backlog = await this.collection();\n const stale = await backlog.find(staleClaim).toArray();\n return this.claimAll(stale, staleClaim, now);\n }\n\n async claimOldestNeverClaimed(\n count: number,\n now: Date,\n ): Promise<StoredEntry[]> {\n if (count <= 0) return [];\n const backlog = await this.collection();\n const oldest = await backlog\n .find(NEVER_CLAIMED, { sort: OLDEST_FIRST, limit: count })\n .toArray();\n return this.claimAll(oldest, NEVER_CLAIMED, now);\n }\n\n async removeAll(ids: ObjectId[]): Promise<void> {\n if (ids.length === 0) return;\n const backlog = await this.collection();\n await backlog.deleteMany({ _id: { $in: ids } });\n }\n\n private async claimAll(\n entries: StoredEntry[],\n stillClaimable: Filter<BacklogEntry>,\n claimedAt: Date,\n ): Promise<StoredEntry[]> {\n if (entries.length === 0) return [];\n const ids = entries.map(({ _id }) => _id);\n const backlog = await this.collection();\n const { modifiedCount } = await backlog.updateMany(\n { _id: { $in: ids }, ...stillClaimable },\n { $set: { claimedAt } },\n );\n if (modifiedCount < entries.length) {\n return this.whatThisClaimTook(ids, claimedAt);\n }\n return entries;\n }\n\n private async whatThisClaimTook(\n ids: ObjectId[],\n claimedAt: Date,\n ): Promise<StoredEntry[]> {\n const backlog = await this.collection();\n return backlog.find({ _id: { $in: ids }, claimedAt }).toArray();\n }\n\n private async collection(): Promise<Collection<BacklogEntry>> {\n const db = await this.connection.connect();\n return db.collection<BacklogEntry>(collectionNameOf(this.spoolName));\n }\n}\n\nfunction collectionNameOf(spoolName: string): string {\n return `${BACKLOG_COLLECTION_PREFIX}${spoolName}`;\n}\n\nfunction secondsOf(moment: Date): number {\n return Math.floor(moment.getTime() / MS_PER_SECOND);\n}\n","import { ObjectId } from \"mongodb\";\nimport { linkIdOf, linkOfItsRun } from \"@/queues\";\n\nexport interface ItemLink {\n itemId: ObjectId;\n link: number;\n}\n\nconst SPOOL_JOB_ID_PREFIX = \"spool\";\n\nconst AN_ITEM_ID = /^[0-9a-f]{24}$/;\n\nexport function spoolJobId(\n spoolName: string,\n { itemId, link }: ItemLink,\n): string {\n return linkIdOf({\n runId: `${prefixOf(spoolName)}${itemId.toHexString()}`,\n link,\n });\n}\n\nexport function isALinkOfAnItem(spoolName: string, jobId: string): boolean {\n const prefix = prefixOf(spoolName);\n const { runId } = linkOfItsRun(jobId);\n return (\n runId.startsWith(prefix) && AN_ITEM_ID.test(runId.slice(prefix.length))\n );\n}\n\nexport function itemLinkOf(spoolName: string, jobId: string): ItemLink {\n if (!isALinkOfAnItem(spoolName, jobId)) {\n throw notALinkOfAnItem(spoolName, jobId);\n }\n const { runId, link } = linkOfItsRun(jobId);\n const itemId = runId.slice(prefixOf(spoolName).length);\n return { itemId: ObjectId.createFromHexString(itemId), link };\n}\n\nfunction prefixOf(spoolName: string): string {\n return `${SPOOL_JOB_ID_PREFIX}:${spoolName}:`;\n}\n\nfunction notALinkOfAnItem(spoolName: string, jobId: string): Error {\n return new Error(\n `[ravenflow] \"${jobId}\" is not the job id of a link of an item of the spool \"${spoolName}\".`,\n );\n}\n","import type { Queue } from \"bullmq\";\nimport type { ObjectId } from \"mongodb\";\n\nimport { itemLinkOf } from \"./spool-job-id\";\n\nexport class ItemRuns {\n constructor(\n private readonly queue: Queue,\n private readonly spoolName: string,\n ) {}\n\n async goOnTo(linkId: string): Promise<void> {\n const { itemId, link } = itemLinkOf(this.spoolName, linkId);\n const client = await this.queue.client;\n await client.set(this.currentLinkKeyOf(itemId), String(link));\n }\n\n async currentLinksOf(itemIds: ObjectId[]): Promise<number[]> {\n if (itemIds.length === 0) return [];\n const client = await this.queue.client;\n const links = await client.mget(\n itemIds.map((itemId) => this.currentLinkKeyOf(itemId)),\n );\n return links.map((link) => Number(link ?? 0));\n }\n\n async forget(itemIds: ObjectId[]): Promise<void> {\n if (itemIds.length === 0) return;\n const client = await this.queue.client;\n await client.del(itemIds.map((itemId) => this.currentLinkKeyOf(itemId)));\n }\n\n private currentLinkKeyOf(itemId: ObjectId): string {\n return this.queue.toKey(\n `rav:spool-run:${this.spoolName}:${itemId.toHexString()}`,\n );\n }\n}\n","import type { AnyJob } from \"@/job\";\nimport type { MongoConnection } from \"@/mongo/connection\";\nimport { Backlog } from \"@/spools\";\n\nexport function buildBacklog(\n definition: AnyJob,\n mongo: MongoConnection,\n): Backlog | undefined {\n const spool = definition.trigger?.spool;\n if (!spool) return undefined;\n return new Backlog(spool.name, mongo);\n}\n","import type { JobControlPlane, JobControls } from \"@/control-plane\";\nimport type { Backlog } from \"@/spools\";\n\nimport type {\n AnyJobControls,\n ClockFedControls,\n ExecutionControls,\n ProxiedJob,\n SpoolFedControls,\n} from \"./types\";\n\ntype SetLevers = (patch: Partial<JobControls>) => Promise<void>;\n\nexport function buildControls(\n job: ProxiedJob,\n plane: JobControlPlane,\n): AnyJobControls {\n const setLevers: SetLevers = (patch) => plane.write(job.name, patch);\n\n if (job.backlog) return spoolFedControls(setLevers, job.backlog);\n if (isClockFed(job)) return clockFedControls(setLevers);\n\n return executionControls(setLevers);\n}\n\nfunction isClockFed(job: ProxiedJob): boolean {\n return typeof job.definition.trigger?.cron === \"string\";\n}\n\nfunction executionControls(setLevers: SetLevers): ExecutionControls {\n return {\n pauseExecution: () => setLevers({ executionPaused: true }),\n resumeExecution: () => setLevers({ executionPaused: false }),\n };\n}\n\nfunction clockFedControls(setLevers: SetLevers): ClockFedControls {\n return {\n ...executionControls(setLevers),\n pauseTrigger: () => setLevers({ triggerPaused: true }),\n resumeTrigger: () => setLevers({ triggerPaused: false }),\n };\n}\n\nfunction spoolFedControls(\n setLevers: SetLevers,\n backlog: Backlog,\n): SpoolFedControls {\n return {\n ...clockFedControls(setLevers),\n pauseIngest: () => setLevers({ ingestPaused: true }),\n resumeIngest: () => setLevers({ ingestPaused: false }),\n purgeBacklog: () => backlog.purge(),\n };\n}\n","import type { JobsOptions } from \"bullmq\";\nimport { namespacedDeduplicationId } from \"@/job\";\n\nimport type { ProxiedJob, SendArguments } from \"./types\";\n\nexport function deduplicationOptions(\n job: ProxiedJob,\n sent: SendArguments,\n): JobsOptions {\n const deduplicationId = deduplicationIdOfTheSend(job, sent);\n if (deduplicationId === undefined) return {};\n return {\n deduplication: { id: namespacedDeduplicationId(job.name, deduplicationId) },\n };\n}\n\nfunction deduplicationIdOfTheSend(\n job: ProxiedJob,\n sent: SendArguments,\n): string | undefined {\n const givenId = sent.perCall.deduplicationId;\n if (givenId !== undefined) return givenId;\n\n const declared = job.definition.deduplicate;\n if (declared === undefined) return undefined;\n if (declared === true) return job.name;\n return declared(sent.payload as never);\n}\n","import { Job, type JobsOptions, type Queue } from \"bullmq\";\n\nimport { deduplicationOptions } from \"./deduplication\";\nimport type { ProxiedJob, SendArguments, SendOptions } from \"./types\";\n\ntype Send = (payload: unknown, options?: SendOptions) => Promise<Job>;\n\nexport function buildSend(job: ProxiedJob): Send {\n return async (payload, perCall = {}) => {\n const options = addOptions(job, { payload, perCall });\n const added = await job.queue.add(job.name, payload, options);\n if (!options.deduplication) return added;\n return jobHoldingTheDeduplicationId(job.queue, added);\n };\n}\n\nfunction addOptions(job: ProxiedJob, sent: SendArguments): JobsOptions {\n return {\n ...job.declaredOptions,\n ...queueingOptions(sent.perCall),\n ...deduplicationOptions(job, sent),\n };\n}\n\nfunction queueingOptions(perCall: SendOptions): JobsOptions {\n const options: JobsOptions = {};\n if (perCall.delayMs !== undefined) options.delay = perCall.delayMs;\n if (perCall.priority !== undefined) options.priority = perCall.priority;\n return options;\n}\n\nasync function jobHoldingTheDeduplicationId(\n queue: Queue,\n added: Job,\n): Promise<Job> {\n return (await Job.fromId(queue, String(added.id))) ?? added;\n}\n","import type { ControlReads } from \"@/control-plane\";\nimport type { Backlog, SpoolItem } from \"@/spools\";\n\nimport type { SpoolIngest } from \"./types\";\n\nexport function buildSpoolIngest(\n jobName: string,\n backlog: Backlog,\n controls: ControlReads,\n): SpoolIngest<SpoolItem> {\n return {\n push: async (item) => {\n await refuseIfIngestPaused(jobName, controls);\n return backlog.push(item);\n },\n pushMany: async (items) => {\n await refuseIfIngestPaused(jobName, controls);\n return backlog.pushMany(items);\n },\n };\n}\n\nasync function refuseIfIngestPaused(\n jobName: string,\n controls: ControlReads,\n): Promise<void> {\n const { ingestPaused } = await controls.read(jobName);\n if (ingestPaused) throw new SpoolIngestPausedError(jobName);\n}\n\nexport class SpoolIngestPausedError extends Error {\n constructor(public readonly job: string) {\n super(\n `[ravenflow] the spool feeding \"${job}\" is not accepting items: its ingest is paused. Call client.jobs.${job}.controls.resumeIngest() to reopen it.`,\n );\n this.name = \"SpoolIngestPausedError\";\n }\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\nimport type { SpoolItem } from \"@/spools\";\n\nimport { buildBacklog } from \"./build-backlog\";\nimport { buildControls } from \"./controls\";\nimport { buildSend } from \"./send\";\nimport { buildSpoolIngest } from \"./spool-ingest\";\nimport type {\n JobProxiesRuntime,\n JobSend,\n JobsProxy,\n ProxiedJob,\n SpoolIngest,\n} from \"./types\";\n\nexport function initJobProxies<TConfig extends RavenflowConfig>(\n config: TConfig,\n runtime: JobProxiesRuntime,\n): JobsProxy<TConfig[\"jobs\"]> {\n const proxies: Record<string, object> = {};\n\n for (const [name, definition] of Object.entries<AnyJob>(config.jobs)) {\n const job: ProxiedJob = {\n name,\n definition,\n queue: runtime.queues[definition.queue ?? config.defaultQueue],\n declaredOptions: buildJobOptions(definition),\n backlog: buildBacklog(definition, runtime.mongo),\n };\n\n proxies[name] = {\n ...buildSendOrIngest(job, runtime.controls),\n controls: buildControls(job, runtime.controls),\n };\n }\n\n return proxies as unknown as JobsProxy<TConfig[\"jobs\"]>;\n}\n\nfunction buildSendOrIngest(\n job: ProxiedJob,\n controls: ControlReads,\n): JobSend<unknown, unknown> | SpoolIngest<SpoolItem> {\n if (job.backlog) return buildSpoolIngest(job.name, job.backlog, controls);\n return { send: buildSend(job) };\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport { validateConfig } from \"@/config/validate-config\";\nimport { initControlPlane } from \"@/control-plane\";\nimport { createLogger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\nimport { closeQueues, openQueues } from \"@/queues\";\n\nimport { initJobProxies } from \"./job-proxy\";\nimport type {\n RavenflowClient,\n RavenflowClientOptions,\n} from \"./ravenflow-client\";\n\nexport function createRavenflowClient<TConfig extends RavenflowConfig>(\n config: TConfig,\n options: RavenflowClientOptions,\n): RavenflowClient<TConfig> {\n validateConfig(config);\n const logger = createLogger(config.logger);\n const mongo = new MongoConnection(options.mongo);\n const queues = openQueues(config, options.redis);\n const controlPlane = initControlPlane({ redis: options.redis, mongo, logger });\n\n return {\n jobs: initJobProxies(config, { queues, mongo, controls: controlPlane }),\n close: async () => {\n await controlPlane.close();\n await closeQueues(queues);\n await mongo.close();\n },\n };\n}\n","import type { ConnectionOptions as RedisConnectionOptions } from \"bullmq\";\nimport {\n initControlPlane,\n type ControlPlane,\n type ControlReads,\n type JobControls,\n} from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nexport interface ControlPlaneReaderSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n logger: Logger;\n}\n\nexport class ControlPlaneReader implements ControlReads {\n private readonly mirrorConnection: MongoConnection;\n private readonly controlPlane: ControlPlane;\n\n constructor(settings: ControlPlaneReaderSettings) {\n this.mirrorConnection = new MongoConnection(settings.mongo);\n this.controlPlane = initControlPlane({\n redis: settings.redis,\n mongo: this.mirrorConnection,\n logger: settings.logger,\n });\n }\n\n async open(): Promise<void> {\n await this.controlPlane.rehydrate();\n await this.mirrorConnection.close();\n }\n\n read(jobName: string): Promise<JobControls> {\n return this.controlPlane.read(jobName);\n }\n\n async close(): Promise<void> {\n await this.controlPlane.close();\n await this.mirrorConnection.close();\n }\n}\n","import type { Logger } from \"@/logger\";\n\ninterface BullmqErrorSource {\n readonly name: string;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n}\n\nexport function logBullmqErrors(\n source: BullmqErrorSource,\n logger: Logger,\n): void {\n source.on(\"error\", (error) => {\n logger.error(\n { err: error, queue: source.name },\n `[ravenflow] BullMQ reported an error on \"${source.name}\".`,\n );\n });\n}\n","export const MONGODB_DEADLINE_ON_CLOSE_MS = 5_000;\n\nexport async function waitOrCutShort(\n waitingOnMongoDB: Promise<void>,\n cutItShort: () => Promise<void>,\n): Promise<void> {\n if (await settlesBeforeTheDeadline(waitingOnMongoDB)) return;\n await cutItShort();\n await waitingOnMongoDB;\n}\n\nasync function settlesBeforeTheDeadline(work: Promise<void>): Promise<boolean> {\n const deadline = new Promise<boolean>((resolve) => {\n setTimeout(() => resolve(false), MONGODB_DEADLINE_ON_CLOSE_MS).unref();\n });\n return Promise.race([work.then(() => true), deadline]);\n}\n","import { MongoBulkWriteError, type Collection } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\n\nimport { MONGODB_DEADLINE_ON_CLOSE_MS } from \"../mongodb-deadline-on-close\";\n\nimport type { JobResult } from \"./job-result\";\n\nconst FLUSH_INTERVAL_MS = 30_000;\n\nconst JOB_RESULTS_PER_BATCH = 1_000;\n\nconst MAX_UNWRITTEN_JOB_RESULTS = 5_000;\n\nconst PAUSE_BETWEEN_FINAL_FLUSHES_MS = 1_000;\n\nexport class BatchWriter {\n private buffered: JobResult[] = [];\n private writing = 0;\n private flushing: Promise<void> | null = null;\n private mayHoldJobs = true;\n private closed = false;\n private readonly heldJobs: Array<() => void> = [];\n private readonly timer: ReturnType<typeof setInterval>;\n\n constructor(\n private readonly collection: Collection<JobResult>,\n private readonly logger: Logger,\n ) {\n this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);\n this.timer.unref();\n }\n\n add(jobResult: JobResult): void {\n if (this.closed) return this.reportLost(1, \"it arrived after close()\");\n this.buffered.push(jobResult);\n if (this.buffered.length >= JOB_RESULTS_PER_BATCH) this.flush();\n }\n\n async waitForRoom(): Promise<void> {\n if (this.mustHoldJobs()) await this.holdJob();\n }\n\n stopHoldingJobs(): void {\n this.mayHoldJobs = false;\n this.releaseHeldJobs();\n }\n\n async close(): Promise<void> {\n clearInterval(this.timer);\n this.stopHoldingJobs();\n await this.flushUntil(Date.now() + MONGODB_DEADLINE_ON_CLOSE_MS);\n this.closed = true;\n this.dropWhatIsLeft();\n }\n\n private async holdJob(): Promise<void> {\n this.flush();\n await new Promise<void>((resolve) => this.heldJobs.push(resolve));\n }\n\n private mustHoldJobs(): boolean {\n return this.mayHoldJobs && this.unwritten() >= MAX_UNWRITTEN_JOB_RESULTS;\n }\n\n private unwritten(): number {\n return this.buffered.length + this.writing;\n }\n\n private releaseHeldJobs(): void {\n if (this.mustHoldJobs()) return;\n for (const release of this.heldJobs.splice(0)) release();\n }\n\n private async flush(): Promise<void> {\n if (this.flushing) return this.flushing;\n if (this.buffered.length === 0) return;\n\n this.flushing = this.writeBuffered();\n try {\n await this.flushing;\n } finally {\n this.flushing = null;\n this.releaseHeldJobs();\n }\n }\n\n private async writeBuffered(): Promise<void> {\n const batch = this.buffered;\n this.buffered = [];\n this.writing = batch.length;\n try {\n await this.collection.insertMany(batch, {\n ordered: false,\n ignoreUndefined: true,\n });\n } catch (error) {\n this.keepUnlessLost(batch, error);\n } finally {\n this.writing = 0;\n }\n }\n\n private keepUnlessLost(batch: JobResult[], error: unknown): void {\n const refused = countRefusedByMongo(error);\n if (refused > 0) return this.reportLost(refused, \"MongoDB refused them\");\n if (this.closed) return;\n\n this.buffered = [...batch, ...this.buffered];\n this.logger.warn(\n { err: error, jobResults: batch.length },\n \"[ravenflow] job results could not be written; they are kept for the next flush.\",\n );\n }\n\n private async flushUntil(deadline: number): Promise<void> {\n while (this.unwritten() > 0 && Date.now() < deadline) {\n await untilDeadline(this.flush(), deadline);\n if (this.unwritten() > 0) {\n await pause(\n Math.min(PAUSE_BETWEEN_FINAL_FLUSHES_MS, deadline - Date.now()),\n );\n }\n }\n }\n\n private dropWhatIsLeft(): void {\n const left = this.unwritten();\n this.buffered = [];\n if (left === 0) return;\n this.reportLost(\n left,\n `the final flush gave up after ${MONGODB_DEADLINE_ON_CLOSE_MS}ms`,\n );\n }\n\n private reportLost(count: number, why: string): void {\n this.logger.error(\n { lost: count },\n `[ravenflow] ${count} job results were not written: ${why}.`,\n );\n }\n}\n\nfunction countRefusedByMongo(error: unknown): number {\n if (!(error instanceof MongoBulkWriteError)) return 0;\n return [error.writeErrors].flat().length;\n}\n\nfunction untilDeadline(work: Promise<void>, deadline: number): Promise<void> {\n return Promise.race([work, pause(deadline - Date.now())]);\n}\n\nfunction pause(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, Math.max(0, ms)).unref();\n });\n}\n","import type { Collection, Db, IndexDescription } from \"mongodb\";\n\nimport type { JobResult } from \"./job-result\";\n\nconst JOB_RESULTS_COLLECTION = \"rav:job-results\";\n\nconst SECONDS_PER_HOUR = 3_600;\n\nconst ON_FINISHED_AT = { finishedAt: 1 } as const;\n\nconst QUERY_INDEXES: IndexDescription[] = [\n { key: { jobName: 1, finishedAt: -1 } },\n { key: { status: 1, finishedAt: -1 } },\n];\n\nexport function jobResultsCollection(db: Db): Collection<JobResult> {\n return db.collection<JobResult>(JOB_RESULTS_COLLECTION);\n}\n\nexport async function indexJobResults(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n await jobResultsCollection(db).createIndexes(QUERY_INDEXES);\n await expireJobResultsAfter(db, retentionHours * SECONDS_PER_HOUR);\n}\n\nasync function expireJobResultsAfter(db: Db, seconds: number): Promise<void> {\n const collection = jobResultsCollection(db);\n const index = await indexOnFinishedAt(collection);\n if (index === undefined) return createExpiryIndex(collection, seconds);\n if (index.expireAfterSeconds !== seconds) await changeExpiry(db, seconds);\n}\n\nasync function createExpiryIndex(\n collection: Collection<JobResult>,\n seconds: number,\n): Promise<void> {\n await collection.createIndex(ON_FINISHED_AT, { expireAfterSeconds: seconds });\n}\n\nasync function changeExpiry(db: Db, seconds: number): Promise<void> {\n await db.command({\n collMod: JOB_RESULTS_COLLECTION,\n index: { keyPattern: ON_FINISHED_AT, expireAfterSeconds: seconds },\n });\n}\n\nasync function indexOnFinishedAt(collection: Collection<JobResult>) {\n const indexes = await collection.indexes();\n return indexes.find((index) => isOnFinishedAtAlone(index.key));\n}\n\nfunction isOnFinishedAtAlone(key: Record<string, unknown>): boolean {\n const fields = Object.keys(key);\n return fields.length === 1 && key.finishedAt === 1;\n}\n","import { DelayedError, type Job } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\n\nconst DEFERRED_FOR_MS = 60_000;\n\nexport interface ExecutionGateRuntime {\n controls: ControlReads;\n token: string | undefined;\n}\n\nexport async function deferIfItsExecutionIsPaused(\n job: Job,\n runtime: ExecutionGateRuntime,\n): Promise<void> {\n const { executionPaused } = await runtime.controls.read(job.name);\n if (executionPaused) await deferTheJob(job, runtime.token);\n}\n\nasync function deferTheJob(\n job: Job,\n token: string | undefined,\n): Promise<never> {\n await job.moveToDelayed(Date.now() + DEFERRED_FOR_MS, token);\n throw new DelayedError();\n}\n","import { DelayedError, Worker, type Job, type Queue } from \"bullmq\";\nimport { spacingMsOf, type PacePolicy } from \"@/job\";\n\nconst US_PER_MS = 1_000;\n\nconst KEPT_PAST_THE_LAST_TURN_MS = 10_000;\n\nconst A_TURN_MAY_BE_LATE_BY_MS = 25;\n\nconst SLEPT_IN_PROCESS_UNDER_MS = 500;\n\nconst TAKE_A_TURN = `\nlocal at = redis.call('TIME')\nlocal now = tonumber(at[1]) * 1000000 + tonumber(at[2])\nlocal spacing = tonumber(ARGV[1])\nlocal mayBeLateBy = tonumber(ARGV[2])\nlocal sleptUnder = tonumber(ARGV[3])\nlocal keptMs = tonumber(ARGV[4])\nlocal turn = tonumber(redis.call('HGET', KEYS[2], 'ravPaceTurn'))\nif turn == nil or now - turn > mayBeLateBy then\n turn = tonumber(redis.call('GET', KEYS[1])) or now\n if turn < now then turn = now end\n local untilTheLastTurnMs = math.ceil((turn + spacing - now) / 1000)\n redis.call('SET', KEYS[1], turn + spacing, 'PX', untilTheLastTurnMs + keptMs)\nend\nlocal wait = turn - now\nif wait >= sleptUnder then\n redis.call('HSET', KEYS[2], 'ravPaceTurn', turn)\n return wait\nend\nredis.call('HDEL', KEYS[2], 'ravPaceTurn')\nif wait < 0 then return 0 end\nreturn wait\n`;\n\ninterface PaceRuntime {\n queue: Queue;\n token: string | undefined;\n shutdown: AbortSignal;\n}\n\nexport async function waitForItsTurn(\n job: Job,\n pace: PacePolicy | undefined,\n runtime: PaceRuntime,\n): Promise<void> {\n if (pace === undefined) return;\n if (runtime.shutdown.aborted) return handBackToWait();\n const waitMs = await takeATurn(job, spacingMsOf(pace), runtime.queue);\n if (waitMs >= SLEPT_IN_PROCESS_UNDER_MS) {\n return putOffInDelayed(job, waitMs - SLEPT_IN_PROCESS_UNDER_MS, runtime);\n }\n await sleep(waitMs, runtime.shutdown);\n if (runtime.shutdown.aborted) return handBackToWait();\n}\n\nasync function takeATurn(\n job: Job,\n spacingMs: number,\n queue: Queue,\n): Promise<number> {\n const client = await queue.client;\n const waitUs = await client.eval(\n TAKE_A_TURN,\n 2,\n queue.toKey(`rav:pace:${job.name}`),\n queue.toKey(String(job.id)),\n microseconds(spacingMs),\n microseconds(A_TURN_MAY_BE_LATE_BY_MS),\n microseconds(SLEPT_IN_PROCESS_UNDER_MS),\n String(KEPT_PAST_THE_LAST_TURN_MS),\n );\n return Number(waitUs) / US_PER_MS;\n}\n\nfunction microseconds(ms: number): string {\n return String(Math.round(ms * US_PER_MS));\n}\n\nasync function putOffInDelayed(\n job: Job,\n delayMs: number,\n runtime: PaceRuntime,\n): Promise<never> {\n await job.moveToDelayed(Date.now() + delayMs, runtime.token);\n throw new DelayedError();\n}\n\nfunction handBackToWait(): never {\n throw Worker.RateLimitError();\n}\n\nfunction sleep(ms: number, shutdown: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(wakeUp, ms);\n shutdown.addEventListener(\"abort\", wakeUp, { once: true });\n\n function wakeUp(): void {\n clearTimeout(timer);\n shutdown.removeEventListener(\"abort\", wakeUp);\n resolve();\n }\n });\n}\n","export interface ExecutionSignal {\n signal: AbortSignal;\n detach(): void;\n}\n\nexport function attachExecutionSignal(shutdown: AbortSignal): ExecutionSignal {\n const execution = new AbortController();\n const abort = () => execution.abort(shutdown.reason);\n\n if (shutdown.aborted) abort();\n else shutdown.addEventListener(\"abort\", abort, { once: true });\n\n return {\n signal: execution.signal,\n detach: () => shutdown.removeEventListener(\"abort\", abort),\n };\n}\n","import type { Job } from \"bullmq\";\nimport { format, inspect } from \"node:util\";\nimport type { Logger } from \"@/logger\";\n\ntype LogMethod = (...args: unknown[]) => void;\n\ntype ChildMethod = (...args: unknown[]) => Logger;\n\ntype Fields = Record<string, unknown>;\n\nexport function loggerFor(job: Job, logger: Logger): Logger {\n return new JobLogCopier(job).copyingLines(logger.child({ job: job.name }));\n}\n\nclass JobLogCopier {\n constructor(private readonly job: Job) {}\n\n copyingLines(logger: Logger): Logger {\n return new Proxy(logger, {\n get: (target, property) => {\n const value = Reflect.get(target, property);\n if (property === \"child\") {\n return this.childCopyingLines(target, value as ChildMethod);\n }\n if (!isLevelOf(target, property)) return value;\n return this.levelCopyingLines(target, property, value as LogMethod);\n },\n });\n }\n\n private childCopyingLines(parent: Logger, child: ChildMethod): ChildMethod {\n return (...args) => this.copyingLines(child.apply(parent, args));\n }\n\n private levelCopyingLines(\n logger: Logger,\n level: string,\n log: LogMethod,\n ): LogMethod {\n return (...args) => {\n log.apply(logger, args);\n if (!logger.isLevelEnabled(level)) return;\n this.copyLine(logger, lineOf(level, args, contextOf(logger)));\n };\n }\n\n private copyLine(logger: Logger, line: string): void {\n this.job.log(line).catch((error: unknown) => {\n logger.warn(\n { err: error },\n \"[ravenflow] a log line could not be copied into the job's logs.\",\n );\n });\n }\n}\n\nfunction isLevelOf(\n logger: Logger,\n property: string | symbol,\n): property is string {\n return (\n typeof property === \"string\" &&\n Object.keys(logger.levels.values).includes(property)\n );\n}\n\nfunction contextOf(logger: Logger): Fields {\n const bindings = Object.entries(logger.bindings());\n return Object.fromEntries(bindings.filter(([key]) => key !== \"job\"));\n}\n\nfunction lineOf(level: string, args: unknown[], context: Fields): string {\n const { message, fields } = partsOf(args, context);\n const time = `[${utcTimeOfDay(new Date())}]`;\n const words = [time, `${level.toUpperCase()}:`, message, inlined(fields)];\n return words.filter((word) => word !== \"\").join(\" \");\n}\n\nfunction partsOf(\n [first, ...rest]: unknown[],\n context: Fields,\n): { message: string; fields: Fields } {\n if (first instanceof Error) {\n return { message: format(...rest), fields: { ...context, err: first } };\n }\n if (typeof first === \"object\" && first !== null) {\n return { message: format(...rest), fields: { ...context, ...first } };\n }\n return { message: format(first, ...rest), fields: context };\n}\n\nfunction inlined(fields: Fields): string {\n if (Object.keys(fields).length === 0) return \"\";\n return inspect(fields, { breakLength: Infinity });\n}\n\nfunction utcTimeOfDay(date: Date): string {\n return date.toISOString().slice(11, 23);\n}\n","import type { Job } from \"bullmq\";\nimport type { ChainableCommander } from \"ioredis\";\nimport { deduplicationIdOf } from \"@/job\";\n\nconst RELEASE_IF_THE_LINK_HOLDS_IT = `\nif redis.call(\"GET\", KEYS[1]) == ARGV[1] then\n return redis.call(\"DEL\", KEYS[1])\nend\nreturn 0`;\n\nexport function deduplicationIdHeldBy(job: Job): string | undefined {\n const namespacedId = job.deduplicationId;\n if (namespacedId === undefined) return undefined;\n return deduplicationIdOf(job.name, namespacedId);\n}\n\nexport function releaseTheHoldOf(\n job: Job,\n transaction: ChainableCommander,\n): void {\n const namespacedId = job.deduplicationId;\n if (namespacedId === undefined) return;\n transaction.eval(\n RELEASE_IF_THE_LINK_HOLDS_IT,\n 1,\n `${job.queueQualifiedName}:de:${namespacedId}`,\n String(job.id),\n );\n}\n","import { Job, type JobsOptions, type Queue, type RedisClient } from \"bullmq\";\nimport type { ChainableCommander } from \"ioredis\";\nimport { namespacedDeduplicationId, type Continuation } from \"@/job\";\nimport { buildJobOptions, nextLinkIdOf } from \"@/queues\";\nimport { isALinkOfAnItem, ItemRuns } from \"@/spools\";\n\nimport type { Link } from \"./link\";\nimport { releaseTheHoldOf } from \"./link-deduplication\";\n\ninterface NextLink {\n jobName: string;\n id: string;\n params: unknown;\n options: JobsOptions;\n}\n\nexport async function enqueueNextLink(\n { job, definition }: Link,\n next: Continuation<unknown>,\n queue: Queue,\n): Promise<void> {\n const nextLink = nextLinkOf({ job, definition }, next);\n const spoolName = definition.trigger?.spool?.name;\n if (spoolName !== undefined && isALinkOfAnItem(spoolName, nextLink.id)) {\n refuseAnIdForTheRunOfAnItem(nextLink, next);\n await new ItemRuns(queue, spoolName).goOnTo(nextLink.id);\n }\n await addTheNextLink(job, nextLink, queue);\n}\n\nfunction nextLinkOf(\n { job, definition }: Link,\n next: Continuation<unknown>,\n): NextLink {\n const id = nextLinkIdOf(String(job.id));\n const options: JobsOptions = { ...buildJobOptions(definition), jobId: id };\n if (next.delayMs !== undefined) options.delay = next.delayMs;\n if (next.deduplicationId !== undefined) {\n const namespacedId = namespacedDeduplicationId(\n job.name,\n next.deduplicationId,\n );\n options.deduplication = { id: namespacedId };\n }\n return { jobName: job.name, id, params: next.params, options };\n}\n\nfunction refuseAnIdForTheRunOfAnItem(\n nextLink: NextLink,\n next: Continuation<unknown>,\n): void {\n if (next.deduplicationId === undefined) return;\n throw new Error(\n `[ravenflow] \"${nextLink.jobName}\" passes the deduplication id \"${next.deduplicationId}\" on to the next link of a spool item's run, but an item's run holds no deduplication id: each item runs under a job id of its own.`,\n );\n}\n\nasync function addTheNextLink(\n job: Job,\n nextLink: NextLink,\n queue: Queue,\n): Promise<void> {\n const transaction = (await queue.client).multi();\n releaseTheHoldOf(job, transaction);\n await addWithin(transaction, jobOf(nextLink, queue));\n await commit(transaction, nextLink);\n}\n\nfunction jobOf(nextLink: NextLink, queue: Queue): Job {\n const options = { ...queue.defaultJobOptions, ...nextLink.options };\n return new Job(\n queue,\n nextLink.jobName,\n nextLink.params,\n options,\n nextLink.id,\n );\n}\n\nasync function addWithin(\n transaction: ChainableCommander,\n job: Job,\n): Promise<void> {\n await job.addJob(transaction as unknown as RedisClient);\n}\n\nasync function commit(\n transaction: ChainableCommander,\n nextLink: NextLink,\n): Promise<void> {\n const replies = (await transaction.exec()) ?? [];\n for (const [error] of replies) {\n if (error !== null) throw nextLinkNotEnqueued(nextLink, error);\n }\n}\n\nfunction nextLinkNotEnqueued(nextLink: NextLink, cause: Error): Error {\n return new Error(\n `[ravenflow] the next link of \"${nextLink.jobName}\", ${nextLink.id}, could not be enqueued: ${cause.message}`,\n );\n}\n","import type { Job, Queue } from \"bullmq\";\nimport { continueWith, isContinuation, type JobContext } from \"@/job\";\nimport type { Logger } from \"@/logger\";\n\nimport { attachExecutionSignal } from \"./execution-signal\";\nimport { loggerFor } from \"./job-logger\";\nimport type { Link } from \"./link\";\nimport { deduplicationIdHeldBy } from \"./link-deduplication\";\nimport { enqueueNextLink } from \"./next-link\";\n\nexport interface LinkRuntime {\n shutdown: AbortSignal;\n logger: Logger;\n queue: Queue;\n}\n\nexport async function runLink(\n link: Link,\n runtime: LinkRuntime,\n): Promise<unknown> {\n const outcome = await callHandler(link, runtime);\n if (isContinuation(outcome)) {\n await enqueueNextLink(link, outcome, runtime.queue);\n return undefined;\n }\n return outcome;\n}\n\nasync function callHandler(\n { job, definition }: Link,\n runtime: LinkRuntime,\n): Promise<unknown> {\n const execution = attachExecutionSignal(runtime.shutdown);\n try {\n return await definition.handler(\n contextFor(job, runtime.logger, execution.signal),\n );\n } finally {\n execution.detach();\n }\n}\n\nfunction contextFor(\n job: Job,\n logger: Logger,\n signal: AbortSignal,\n): JobContext<never> {\n return {\n params: job.data as never,\n deduplicationId: deduplicationIdHeldBy(job),\n job,\n logger: loggerFor(job, logger),\n signal,\n continueWith,\n };\n}\n","import type { Job } from \"bullmq\";\n\nconst SKIPPED_BY_TRIGGER_PAUSE = \"skippedByTriggerPause\";\n\ntype Progress = Record<string, unknown>;\n\nexport function wasSkippedByATriggerPause(job: Job): boolean {\n return progressOf(job)[SKIPPED_BY_TRIGGER_PAUSE] === true;\n}\n\nexport async function markSkippedByATriggerPause(job: Job): Promise<void> {\n await job.updateProgress({\n ...progressOf(job),\n [SKIPPED_BY_TRIGGER_PAUSE]: true,\n });\n}\n\nfunction progressOf(job: Job): Progress {\n const { progress } = job;\n if (typeof progress !== \"object\" || progress === null) return {};\n return progress as Progress;\n}\n","import type { Job } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\n\nimport { markSkippedByATriggerPause } from \"./progress-marks\";\n\nexport async function isAnOccurrenceToSkip(\n job: Job,\n controls: ControlReads,\n): Promise<boolean> {\n return (\n wasProducedByItsScheduler(job) &&\n (await controls.read(job.name)).triggerPaused\n );\n}\n\nexport async function skipTheOccurrence(\n job: Job,\n logger: Logger,\n): Promise<void> {\n try {\n await markSkippedByATriggerPause(job);\n } catch (error) {\n warnOfAnUnmarkedSkip(job, error, logger);\n }\n}\n\nfunction wasProducedByItsScheduler(job: Job): boolean {\n return job.repeatJobKey !== undefined;\n}\n\nfunction warnOfAnUnmarkedSkip(job: Job, error: unknown, logger: Logger): void {\n logger.warn(\n { err: error, jobId: job.id },\n `[ravenflow] an occurrence of \"${job.name}\" was skipped, its trigger being paused, but the mark on it was not written to Redis.`,\n );\n}\n","import type { Job, Processor } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\n\nimport type { JobResultsRecorder } from \"../job-results-recorder\";\n\nimport { deferIfItsExecutionIsPaused } from \"./execution-gate\";\nimport { waitForItsTurn } from \"./pace-gate\";\nimport { runLink, type LinkRuntime } from \"./run-link\";\nimport { isAnOccurrenceToSkip, skipTheOccurrence } from \"./trigger-gate\";\n\nexport interface RouterRuntime extends LinkRuntime {\n jobs: Record<string, AnyJob>;\n controls: ControlReads;\n jobResultsRecorder: Pick<JobResultsRecorder, \"waitForRoom\">;\n}\n\nexport function routeByName(runtime: RouterRuntime): Processor {\n const declared = new Map(Object.entries(runtime.jobs));\n\n return async (job: Job, token?: string) => {\n const definition = declared.get(job.name);\n if (!definition) throw undeclaredJobError(job);\n if (await isAnOccurrenceToSkip(job, runtime.controls)) {\n return skipTheOccurrence(job, runtime.logger);\n }\n await deferIfItsExecutionIsPaused(job, {\n controls: runtime.controls,\n token,\n });\n await runtime.jobResultsRecorder.waitForRoom();\n await waitForItsTurn(job, definition.pace, {\n queue: runtime.queue,\n token,\n shutdown: runtime.shutdown,\n });\n startItsClock(job);\n return runLink({ job, definition }, runtime);\n };\n}\n\nfunction startItsClock(job: Job): void {\n job.processedOn = Date.now();\n}\n\nfunction undeclaredJobError(job: Job): Error {\n return new Error(\n `[ravenflow] \"${job.name}\" is not declared on \"${job.queueName}\", the queue this worker serves, so it has no handler to run.`,\n );\n}\n","export const JOB_RESULT_MAX_BYTES = 128 * 1024;\n\nexport const JOB_RESULT_MESSAGE_MAX_CHARS = 2000;\n\nexport const JOB_RESULT_STACK_MAX_CHARS = 8000;\n\nexport const JOB_RESULT_LOGS_MAX_CHARS = 500_000;\n","import type { Logger } from \"@/logger\";\n\nexport interface CauseChainEntry {\n message: string;\n name: string;\n}\n\nexport interface ExtractedError {\n /** Top-level message + \"\\nCaused by: \" + inner.message chain, truncated after joining. */\n message: string;\n /** Top-level stack trace only, truncated. Inner stacks are omitted to bound payload. */\n stack: string;\n /** Normalized chain beyond the top level. Empty array when the top Error has no `cause`. */\n causeChain: CauseChainEntry[];\n}\n\nexport interface ExtractMessageAndStackOptions {\n messageMaxChars: number;\n stackMaxChars: number;\n /** Depth cap to guard against cycles and pathological nesting. Default 5. */\n maxCauseDepth?: number;\n}\n\nconst DEFAULT_MAX_CAUSE_DEPTH = 5;\nconst NAME_MAX_CHARS = 64;\nconst CHAIN_SEPARATOR = \"\\nCaused by: \";\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\nfunction safeGet<T>(getter: () => T, fallback: T): T {\n try {\n return getter();\n } catch {\n return fallback;\n }\n}\n\nfunction isErrorLike(\n value: unknown,\n): value is { message: unknown; name?: unknown } {\n if (typeof value !== \"object\" || value === null) return false;\n return safeGet(() => \"message\" in value, false);\n}\n\nfunction normalizeEntry(\n value: unknown,\n messageMaxChars: number,\n): CauseChainEntry {\n const entryMax = Math.max(1, Math.floor(messageMaxChars / 2));\n if (isErrorLike(value)) {\n const rawMessage = safeGet<unknown>(\n () => (value as { message: unknown }).message,\n undefined,\n );\n const rawName = safeGet<unknown>(\n () => (value as { name?: unknown }).name,\n undefined,\n );\n const message = truncate(\n typeof rawMessage === \"string\"\n ? rawMessage\n : safeGet(() => String(rawMessage), \"\"),\n entryMax,\n );\n const name = truncate(\n typeof rawName === \"string\" ? rawName : \"Error\",\n NAME_MAX_CHARS,\n );\n return { message, name };\n }\n return {\n message: truncate(\n safeGet(() => String(value), \"\"),\n entryMax,\n ),\n name: \"NonError\",\n };\n}\n\nfunction walkCauseChain(\n top: { cause?: unknown },\n maxDepth: number,\n messageMaxChars: number,\n): { chain: CauseChainEntry[]; truncated: boolean } {\n const chain: CauseChainEntry[] = [];\n const seen = new WeakSet<object>();\n if (typeof top === \"object\" && top !== null) seen.add(top);\n\n let current: unknown = safeGet<unknown>(() => top.cause, undefined);\n let truncated = false;\n\n while (current !== undefined && current !== null) {\n if (chain.length >= maxDepth) {\n truncated = true;\n break;\n }\n if (typeof current === \"object\" && current !== null) {\n if (seen.has(current)) {\n truncated = true;\n break;\n }\n seen.add(current);\n }\n\n chain.push(normalizeEntry(current, messageMaxChars));\n\n const hasCause =\n typeof current === \"object\" &&\n current !== null &&\n safeGet(() => \"cause\" in (current as object), false);\n if (hasCause) {\n current = safeGet(\n () => (current as { cause?: unknown }).cause,\n undefined,\n );\n } else {\n break;\n }\n }\n\n return { chain, truncated };\n}\n\nexport function extractMessageAndStack(\n err: unknown,\n options: ExtractMessageAndStackOptions,\n logger: Logger,\n): ExtractedError {\n const { messageMaxChars, stackMaxChars } = options;\n const rawMaxDepth = options.maxCauseDepth ?? DEFAULT_MAX_CAUSE_DEPTH;\n const maxCauseDepth =\n Number.isFinite(rawMaxDepth) && rawMaxDepth >= 1\n ? Math.floor(rawMaxDepth)\n : DEFAULT_MAX_CAUSE_DEPTH;\n\n if (!(err instanceof Error)) {\n return {\n message: truncate(\n safeGet(() => String(err), \"\"),\n messageMaxChars,\n ),\n stack: \"\",\n causeChain: [],\n };\n }\n\n const topMessage = safeGet<string>(() => {\n const m = err.message;\n return typeof m === \"string\" ? m : String(m ?? \"\");\n }, \"\");\n const topStack = safeGet<string>(() => {\n const s = err.stack;\n return typeof s === \"string\" ? s : String(s ?? \"\");\n }, \"\");\n\n const { chain, truncated } = walkCauseChain(\n err as { cause?: unknown },\n maxCauseDepth,\n messageMaxChars,\n );\n\n if (truncated) {\n logger.warn(\n { topMessage: truncate(topMessage, 120) },\n \"extractMessageAndStack: maxCauseDepth reached, truncating cause chain.\",\n );\n }\n\n let joinedMessage = topMessage;\n for (const entry of chain) {\n joinedMessage += `${CHAIN_SEPARATOR}${entry.message}`;\n }\n\n return {\n message: truncate(joinedMessage, messageMaxChars),\n stack: truncate(topStack, stackMaxChars),\n causeChain: chain,\n };\n}\n","import { BSON } from \"mongodb\";\n\n/**\n * What a job handed in or handed back, made safe to store as **native BSON**\n * rather than as a serialised string — so `params.tenantId` is a field a query\n * can filter on instead of a substring to grep (D15).\n *\n * The value space is JSON's, whatever the handler declared: BullMQ holds `data`\n * and `returnvalue` as JSON in Redis, so a `Date` is already a string and a\n * `Map` already `{}` by the time this sees them.\n */\n\n/**\n * Whether to write the field at all, and what to write.\n *\n * `stored: false` rather than a sentinel value, because a field set to\n * `undefined` is one BSON drops — leaving a document whose missing key cannot\n * be told from one written before the key existed.\n */\nexport type Storable = { stored: true; value: unknown } | { stored: false };\n\n/**\n * The value to store, the marker that replaces it, or nothing.\n *\n * Two things a JSON value can be that BSON must not hold, and both are answered\n * by **replacing the whole value** rather than repairing it. A repaired value\n * is the failure this collection exists to end: a document that looks like the\n * truth and is not.\n *\n * `maxBytes` is measured in the bytes BSON will occupy, not in characters: the\n * cap bounds a document, and a document is bytes.\n */\nexport function storableValue(value: unknown, maxBytes: number): Storable {\n if (value === undefined) return { stored: false };\n\n const hostile = firstHostileKey(value);\n if (hostile !== null) {\n return {\n stored: true,\n value: { __ravenflow_omitted: true, hostileKey: hostile },\n };\n }\n\n const bytes = bsonBytesOf(value);\n if (bytes > maxBytes) {\n return { stored: true, value: { __ravenflow_omitted: true, bytes } };\n }\n\n return { stored: true, value };\n}\n\n/**\n * The first key BSON would store but nobody could query, or `null`.\n *\n * **Refused, not sanitised**, and the choice is load-bearing. Rewriting\n * `user.name` to `user_name` keeps the document and breaks the question: a\n * filter on the key the payload actually had comes back empty, which reads as\n * *\"no execution was given that\"* rather than as *\"this was not stored\"*. An\n * absent value asks to be looked into; a renamed one does not.\n *\n * A dot is the path separator every filter is written in, and a leading `$` is\n * how every update operator announces itself. A `$` anywhere else is ordinary.\n */\nfunction firstHostileKey(value: unknown): string | null {\n if (Array.isArray(value)) {\n for (const element of value) {\n const hostile = firstHostileKey(element);\n if (hostile !== null) return hostile;\n }\n return null;\n }\n\n if (value === null || typeof value !== \"object\") return null;\n\n for (const [key, nested] of Object.entries(value)) {\n if (key.includes(\".\") || key.startsWith(\"$\")) return key;\n const hostile = firstHostileKey(nested);\n if (hostile !== null) return hostile;\n }\n return null;\n}\n\n/**\n * Wrapped in a document because `calculateObjectSize` sizes documents and a\n * scalar is not one. The wrapper's overhead is counted, which errs a handful of\n * bytes towards refusing — the safe direction for a cap.\n */\nfunction bsonBytesOf(value: unknown): number {\n return BSON.calculateObjectSize({ v: value });\n}\n","import type { Job } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nimport { extractMessageAndStack } from \"./error-extraction\";\nimport {\n JOB_RESULT_MAX_BYTES,\n JOB_RESULT_MESSAGE_MAX_CHARS,\n JOB_RESULT_STACK_MAX_CHARS,\n} from \"./job-result-limits\";\nimport { storableValue } from \"./storable-value\";\n\nexport interface JobResult {\n jobName: string;\n queue: string;\n status: JobResultStatus;\n params?: unknown;\n result?: unknown;\n error?: JobResultError;\n logs?: string;\n finishedAt: Date;\n durationMs?: number;\n attemptsMade: number;\n}\n\nexport type JobResultStatus = \"succeeded\" | \"failed\";\n\nexport interface JobResultError {\n message: string;\n stack: string;\n causeChain?: Array<{ message: string; name: string }>;\n}\n\nexport function succeededJobResult(\n job: Job,\n result: unknown,\n logs: string,\n): JobResult {\n return {\n ...jobResultOf(job, logs),\n status: \"succeeded\",\n result: stored(result),\n error: lastErrorOf(job),\n };\n}\n\nexport function failedJobResult(\n job: Job,\n error: JobResultError,\n logs: string,\n): JobResult {\n return { ...jobResultOf(job, logs), status: \"failed\", error };\n}\n\nexport function willBeRetried(job: Job): boolean {\n return job.finishedOn === undefined;\n}\n\nexport function jobResultErrorOf(\n error: unknown,\n logger: Logger,\n): JobResultError {\n const { message, stack, causeChain } = extractMessageAndStack(\n error,\n {\n messageMaxChars: JOB_RESULT_MESSAGE_MAX_CHARS,\n stackMaxChars: JOB_RESULT_STACK_MAX_CHARS,\n },\n logger,\n );\n return {\n message,\n stack,\n causeChain: causeChain.length > 0 ? causeChain : undefined,\n };\n}\n\nfunction jobResultOf(job: Job, logs: string): Omit<JobResult, \"status\"> {\n return {\n jobName: job.name,\n queue: job.queueName,\n params: isNothing(job.data) ? undefined : stored(job.data),\n logs: logs === \"\" ? undefined : logs,\n finishedAt: finishedAtOf(job),\n durationMs: durationOf(job),\n attemptsMade: job.attemptsMade,\n };\n}\n\nfunction stored(value: unknown): unknown {\n const storable = storableValue(value, JOB_RESULT_MAX_BYTES);\n return storable.stored ? storable.value : undefined;\n}\n\nfunction isNothing(value: unknown): boolean {\n if (value === undefined || value === null) return true;\n if (typeof value !== \"object\" || Array.isArray(value)) return false;\n return Object.keys(value).length === 0;\n}\n\nfunction lastErrorOf(job: Job): JobResultError | undefined {\n if (!job.failedReason) return undefined;\n const stacks = job.stacktrace ?? [];\n return {\n message: job.failedReason.slice(0, JOB_RESULT_MESSAGE_MAX_CHARS),\n stack: (stacks[stacks.length - 1] ?? \"\").slice(\n 0,\n JOB_RESULT_STACK_MAX_CHARS,\n ),\n };\n}\n\nfunction finishedAtOf(job: Job): Date {\n return job.finishedOn === undefined ? new Date() : new Date(job.finishedOn);\n}\n\nfunction durationOf(job: Job): number | undefined {\n if (job.processedOn === undefined || job.finishedOn === undefined) {\n return undefined;\n }\n return job.finishedOn - job.processedOn;\n}\n","import type { Queue } from \"bullmq\";\nimport type { Logger } from \"@/logger\";\n\nexport async function captureJobLogs(\n queue: Queue,\n jobId: string,\n maxChars: number,\n logger: Logger,\n): Promise<string> {\n if (typeof jobId !== \"string\" || jobId.length === 0) {\n throw new Error(\"captureJobLogs: jobId must be a non-empty string\");\n }\n if (!Number.isInteger(maxChars) || maxChars <= 0) {\n throw new Error(\n `captureJobLogs: maxChars must be a positive integer, got ${maxChars}`,\n );\n }\n\n let logs: string[];\n try {\n const result = await queue.getJobLogs(jobId, 0, -1, true);\n logs = result.logs;\n } catch (err) {\n logger.warn(\n { err, jobId },\n \"[log-capture] failed to fetch job logs — returning empty string\",\n );\n return \"\";\n }\n\n const joined = logs.join(\"\\n\");\n if (joined.length <= maxChars) return joined;\n\n const originalLen = joined.length;\n let tailLen = maxChars;\n let marker = \"\";\n for (let i = 0; i < 3; i++) {\n marker = `[truncated — showing last ${tailLen} of ${originalLen} chars]\\n`;\n if (marker.length >= maxChars) {\n return marker.slice(0, maxChars);\n }\n tailLen = maxChars - marker.length;\n }\n return marker + joined.slice(-tailLen);\n}\n","import type { Job, Queue, Worker } from \"bullmq\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\n\nimport { wasSkippedByATriggerPause } from \"../job-router\";\n\nimport type { BatchWriter } from \"./batch-writer\";\nimport { JOB_RESULT_LOGS_MAX_CHARS } from \"./job-result-limits\";\nimport {\n failedJobResult,\n jobResultErrorOf,\n succeededJobResult,\n willBeRetried,\n} from \"./job-result\";\nimport { captureJobLogs } from \"./log-capture\";\n\nexport interface JobResultsListenerSettings {\n queue: Queue;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n batchWriter: Pick<BatchWriter, \"add\">;\n}\n\nexport class JobResultsListener {\n private readonly declared: Set<string>;\n private readonly resultsInProgress = new Set<Promise<void>>();\n\n constructor(private readonly settings: JobResultsListenerSettings) {\n this.declared = new Set(Object.keys(settings.jobs));\n }\n\n listenTo(worker: Worker): void {\n worker.on(\"completed\", (job, result) => {\n if (wasSkippedByATriggerPause(job)) return;\n this.recordIfDeclared(job, () => this.recordSuccess(job, result));\n });\n worker.on(\"failed\", (job, error) => {\n if (job === undefined || willBeRetried(job)) return;\n this.recordIfDeclared(job, () => this.recordFailure(job, error));\n });\n }\n\n async waitForResultsInProgress(): Promise<void> {\n while (this.resultsInProgress.size > 0) {\n await Promise.allSettled([...this.resultsInProgress]);\n }\n }\n\n private recordIfDeclared(job: Job, record: () => Promise<void>): void {\n if (!this.declared.has(job.name)) return;\n this.track(job, record);\n }\n\n private track(job: Job, record: () => Promise<void>): void {\n const inProgress = record()\n .catch((error: unknown) => this.warnOfALostResult(job, error))\n .finally(() => this.resultsInProgress.delete(inProgress));\n this.resultsInProgress.add(inProgress);\n }\n\n private async recordSuccess(job: Job, result: unknown): Promise<void> {\n const logs = await this.logsOf(job);\n this.settings.batchWriter.add(succeededJobResult(job, result, logs));\n }\n\n private async recordFailure(job: Job, error: Error): Promise<void> {\n const logs = await this.logsOf(job);\n const failure = jobResultErrorOf(error, this.settings.logger);\n this.settings.batchWriter.add(failedJobResult(job, failure, logs));\n }\n\n private async logsOf(job: Job): Promise<string> {\n return captureJobLogs(\n this.settings.queue,\n String(job.id),\n JOB_RESULT_LOGS_MAX_CHARS,\n this.settings.logger,\n );\n }\n\n private warnOfALostResult(job: Job, error: unknown): void {\n this.settings.logger.warn(\n { err: error, jobId: job.id },\n `[ravenflow] the job result of \"${job.name}\" #${job.id} could not be recorded.`,\n );\n }\n}\n","import type { Queue, Worker } from \"bullmq\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nimport { BatchWriter } from \"./batch-writer\";\nimport {\n indexJobResults,\n jobResultsCollection,\n} from \"./job-results-collection\";\nimport { JobResultsListener } from \"./job-results-listener\";\n\nexport interface JobResultsRecorderSettings {\n mongo: string;\n retentionHours: number;\n queue: Queue;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n}\n\nexport type JobResultsRecorderOpening =\n | { opened: true }\n | { opened: false; because: string };\n\ninterface ActiveRecording {\n writer: BatchWriter;\n listener: JobResultsListener;\n}\n\nexport class JobResultsRecorder {\n private readonly connection: MongoConnection;\n private recording: ActiveRecording | null = null;\n\n constructor(private readonly settings: JobResultsRecorderSettings) {\n this.connection = new MongoConnection(settings.mongo);\n }\n\n async open(worker: Worker): Promise<void> {\n try {\n this.recording = await this.openRecording(worker);\n } catch (error) {\n await this.connection.close();\n throw error;\n }\n }\n\n async waitForRoom(): Promise<void> {\n await this.recording?.writer.waitForRoom();\n }\n\n stopHoldingJobs(): void {\n this.recording?.writer.stopHoldingJobs();\n }\n\n async close(): Promise<void> {\n await this.closeRecording();\n await this.connection.close();\n }\n\n private async openRecording(worker: Worker): Promise<ActiveRecording> {\n const { queue, jobs, logger } = this.settings;\n const db = await this.connection.connect();\n await indexJobResults(db, this.settings.retentionHours);\n\n const writer = new BatchWriter(jobResultsCollection(db), logger);\n const listener = new JobResultsListener({\n queue,\n jobs,\n logger,\n batchWriter: writer,\n });\n listener.listenTo(worker);\n return { writer, listener };\n }\n\n private async closeRecording(): Promise<void> {\n const recording = this.recording;\n this.recording = null;\n if (!recording) return;\n\n await recording.listener.waitForResultsInProgress();\n await recording.writer.close();\n }\n}\n","import type { Collection, Db } from \"mongodb\";\n\nconst AGGREGATED_RESULTS_COLLECTION = \"rav:aggregated-results\";\n\nconst SECONDS_PER_HOUR = 3_600;\n\nconst THE_BEGINNING = new Date(0);\n\nexport interface AggregatedResult {\n minute: Date;\n job: { name: string; queue: string };\n succeeded: number;\n failed: number;\n}\n\nexport interface Minutes {\n from: Date;\n until: Date;\n}\n\nexport async function createAggregatedResultsIfMissing(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n if (await isMissing(db)) await createTimeSeries(db, retentionHours);\n}\n\nexport async function changeRetentionIfItDiffers(\n db: Db,\n retentionHours: number,\n): Promise<void> {\n if (await retentionDiffers(db, retentionHours)) {\n await changeRetention(db, retentionHours);\n }\n}\n\nexport async function watermarkOf(db: Db): Promise<Date> {\n const newest = await aggregatedResultsCollection(db).findOne(\n {},\n { sort: { minute: -1 } },\n );\n if (newest === null) return THE_BEGINNING;\n return newest.minute;\n}\n\nexport async function replaceAggregatedResults(\n db: Db,\n minutes: Minutes,\n aggregatedResults: AggregatedResult[],\n): Promise<void> {\n const collection = aggregatedResultsCollection(db);\n await collection.deleteMany({\n minute: { $gte: minutes.from, $lt: minutes.until },\n });\n if (aggregatedResults.length === 0) return;\n await collection.insertMany(aggregatedResults, {\n forceServerObjectId: true,\n });\n}\n\nasync function isMissing(db: Db): Promise<boolean> {\n return (await collectionInfoOf(db)) === undefined;\n}\n\nasync function retentionDiffers(\n db: Db,\n retentionHours: number,\n): Promise<boolean> {\n const info = await collectionInfoOf(db);\n return info?.options?.expireAfterSeconds !== secondsOf(retentionHours);\n}\n\nasync function createTimeSeries(db: Db, retentionHours: number): Promise<void> {\n await db.createCollection(AGGREGATED_RESULTS_COLLECTION, {\n timeseries: {\n timeField: \"minute\",\n metaField: \"job\",\n granularity: \"minutes\",\n },\n expireAfterSeconds: secondsOf(retentionHours),\n });\n}\n\nasync function changeRetention(db: Db, retentionHours: number): Promise<void> {\n await db.command({\n collMod: AGGREGATED_RESULTS_COLLECTION,\n expireAfterSeconds: secondsOf(retentionHours),\n });\n}\n\nasync function collectionInfoOf(db: Db) {\n const [info] = await db\n .listCollections(\n { name: AGGREGATED_RESULTS_COLLECTION },\n { nameOnly: false },\n )\n .toArray();\n return info;\n}\n\nfunction secondsOf(hours: number): number {\n return hours * SECONDS_PER_HOUR;\n}\n\nfunction aggregatedResultsCollection(db: Db): Collection<AggregatedResult> {\n return db.collection<AggregatedResult>(AGGREGATED_RESULTS_COLLECTION);\n}\n","import type { Db } from \"mongodb\";\nimport {\n jobResultsCollection,\n type JobResult,\n} from \"@/worker/job-results-recorder\";\n\nimport {\n replaceAggregatedResults,\n watermarkOf,\n type AggregatedResult,\n type Minutes,\n} from \"./aggregated-results-collection\";\n\nconst MINUTE_MS = 60_000;\n\nconst HOUR_MS = 60 * MINUTE_MS;\n\nconst COUNT_MINUTES_OLDER_THAN_MS = 2 * MINUTE_MS;\n\nconst RECOUNT_WINDOW_MS = 10 * MINUTE_MS;\n\nexport async function aggregateJobResults(\n db: Db,\n now: Date,\n retentionHours: number,\n): Promise<void> {\n const minutes = await minutesToCount(db, now, retentionHours);\n await replaceAggregatedResults(db, minutes, await countByMinute(db, minutes));\n}\n\nasync function minutesToCount(\n db: Db,\n now: Date,\n retentionHours: number,\n): Promise<Minutes> {\n const until = minuteOf(now.getTime() - COUNT_MINUTES_OLDER_THAN_MS);\n const recountFrom = new Date(until.getTime() - RECOUNT_WINDOW_MS);\n const oldestKept = minuteOf(now.getTime() - retentionHours * HOUR_MS);\n const counted = earliestOf(await watermarkOf(db), recountFrom);\n return { from: latestOf(counted, oldestKept), until };\n}\n\nasync function countByMinute(\n db: Db,\n { from, until }: Minutes,\n): Promise<AggregatedResult[]> {\n return jobResultsCollection(db)\n .aggregate<AggregatedResult>([\n { $match: { finishedAt: { $gte: from, $lt: until } } },\n {\n $group: {\n _id: {\n minute: { $dateTrunc: { date: \"$finishedAt\", unit: \"minute\" } },\n name: \"$jobName\",\n queue: \"$queue\",\n },\n succeeded: { $sum: countWhenStatusIs(\"succeeded\") },\n failed: { $sum: countWhenStatusIs(\"failed\") },\n },\n },\n {\n $project: {\n _id: 0,\n minute: \"$_id.minute\",\n job: { name: \"$_id.name\", queue: \"$_id.queue\" },\n succeeded: 1,\n failed: 1,\n },\n },\n { $sort: { minute: 1, \"job.name\": 1 } },\n ])\n .toArray();\n}\n\nfunction countWhenStatusIs(status: JobResult[\"status\"]): object {\n return { $cond: [{ $eq: [\"$status\", status] }, 1, 0] };\n}\n\nfunction minuteOf(timestamp: number): Date {\n return new Date(Math.floor(timestamp / MINUTE_MS) * MINUTE_MS);\n}\n\nfunction earliestOf(first: Date, second: Date): Date {\n return first < second ? first : second;\n}\n\nfunction latestOf(first: Date, second: Date): Date {\n return first > second ? first : second;\n}\n","import {\n Queue,\n Worker,\n type ConnectionOptions as RedisConnectionOptions,\n} from \"bullmq\";\nimport type { Db } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\n\nimport { logBullmqErrors } from \"../../log-bullmq-errors\";\nimport { waitOrCutShort } from \"../../mongodb-deadline-on-close\";\n\nimport { aggregateJobResults } from \"./aggregate-job-results\";\nimport {\n changeRetentionIfItDiffers,\n createAggregatedResultsIfMissing,\n} from \"./aggregated-results-collection\";\n\nconst AGGREGATOR_QUEUE = \"rav-internal-aggregate-results\";\n\nconst TICK_NAME = \"aggregate-results\";\n\nconst AT_THE_FIFTEENTH_SECOND = \"15 * * * * *\";\n\nconst ONE_TICK_AT_A_TIME = 1;\n\nconst TICKS_KEPT = 100;\n\nexport interface JobResultsAggregatorSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n retentionHours: number;\n logger: Logger;\n}\n\ninterface Ticking {\n aggregatorQueue: Queue;\n tickWorker: Worker;\n}\n\nexport class JobResultsAggregator {\n private readonly connection: MongoConnection;\n private ticking: Ticking | null = null;\n\n constructor(private readonly settings: JobResultsAggregatorSettings) {\n this.connection = new MongoConnection(settings.mongo);\n }\n\n async open(): Promise<void> {\n const aggregatorQueue = new Queue(AGGREGATOR_QUEUE, {\n connection: this.settings.redis,\n });\n logBullmqErrors(aggregatorQueue, this.settings.logger);\n const tickWorker = this.openTickWorker();\n this.ticking = { aggregatorQueue, tickWorker };\n await aggregatorQueue.setGlobalConcurrency(ONE_TICK_AT_A_TIME);\n await scheduleTicks(aggregatorQueue);\n }\n\n async stopTicking(): Promise<void> {\n const ticking = this.ticking;\n this.ticking = null;\n if (!ticking) return;\n\n await waitOrCutShort(ticking.tickWorker.close(), () =>\n this.connection.close(),\n );\n await ticking.aggregatorQueue.close();\n }\n\n async close(): Promise<void> {\n await this.stopTicking();\n await this.connection.close();\n }\n\n private openTickWorker(): Worker {\n const worker = new Worker(AGGREGATOR_QUEUE, () => this.tick(), {\n connection: this.settings.redis,\n });\n worker.on(\"failed\", (_tick, error) => this.warnOfAFailedTick(error));\n logBullmqErrors(worker, this.settings.logger);\n return worker;\n }\n\n private async tick(): Promise<void> {\n const db = await this.connection.connect();\n const { retentionHours } = this.settings;\n await createAggregatedResultsIfMissing(db, retentionHours);\n await this.applyTheConfiguredRetention(db);\n await aggregateJobResults(db, new Date(), retentionHours);\n }\n\n private async applyTheConfiguredRetention(db: Db): Promise<void> {\n try {\n await changeRetentionIfItDiffers(db, this.settings.retentionHours);\n } catch (error) {\n this.warnOfAnUnchangedRetention(error);\n }\n }\n\n private warnOfAFailedTick(error: Error): void {\n this.settings.logger.warn(\n { err: error },\n \"[ravenflow] a tick of the job results aggregator failed; its minutes are counted by the next tick that succeeds.\",\n );\n }\n\n private warnOfAnUnchangedRetention(error: unknown): void {\n this.settings.logger.warn(\n { err: error },\n `[ravenflow] the aggregated results' retention could not be changed to ${this.settings.retentionHours} hours; they are counted all the same, and kept as long as before.`,\n );\n }\n}\n\nasync function scheduleTicks(queue: Queue): Promise<void> {\n await queue.upsertJobScheduler(\n TICK_NAME,\n { pattern: AT_THE_FIFTEENTH_SECOND },\n {\n name: TICK_NAME,\n opts: {\n removeOnComplete: { count: TICKS_KEPT },\n removeOnFail: { count: TICKS_KEPT },\n },\n },\n );\n}\n","import type { Queue } from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { Logger } from \"@/logger\";\nimport {\n ItemRuns,\n claimHoldMsOf,\n mayPull,\n roomUnderTheCeiling,\n spoolJobId,\n type Backlog,\n type StoredEntry,\n} from \"@/spools\";\n\nimport type { Stage } from \"./stage\";\n\nexport interface FeedingRuntime {\n backlog: Backlog;\n queue: Queue;\n controls: ControlReads;\n logger: Logger;\n}\n\ninterface Release {\n entry: StoredEntry;\n link: number;\n}\n\nexport async function feedSpool(\n stage: Stage,\n runtime: FeedingRuntime,\n): Promise<void> {\n await expireWhatWaitedTooLong(stage, runtime);\n if (await isItsTriggerPaused(stage, runtime.controls)) return;\n if (!(await mayPull(stage.spool))) return;\n const now = new Date();\n const staleRuns = await reclaimTheStaleRuns(stage, runtime, now);\n const newRuns = await claimWhatTheCeilingAllows(stage, runtime.backlog, now);\n await release(stage, [...staleRuns, ...newRuns], runtime.queue);\n}\n\nasync function expireWhatWaitedTooLong(\n stage: Stage,\n { backlog, logger }: FeedingRuntime,\n): Promise<void> {\n const { expireUnclaimedAfterMs } = stage.spool;\n if (expireUnclaimedAfterMs === undefined) return;\n const pushedBefore = new Date(Date.now() - expireUnclaimedAfterMs);\n const expired = await backlog.expireUnclaimedPushedBefore(pushedBefore);\n if (expired > 0) warnOfExpiredItems(stage, expired, logger);\n}\n\nfunction warnOfExpiredItems(\n stage: Stage,\n expired: number,\n logger: Logger,\n): void {\n const { name, expireUnclaimedAfterMs } = stage.spool;\n logger.warn(\n { spool: name, expired },\n `[ravenflow] ${expired} items of the spool \"${name}\" expired: they waited more than ${expireUnclaimedAfterMs} ms without being claimed.`,\n );\n}\n\nasync function isItsTriggerPaused(\n stage: Stage,\n controls: ControlReads,\n): Promise<boolean> {\n const { triggerPaused } = await controls.read(stage.jobName);\n return triggerPaused;\n}\n\nasync function reclaimTheStaleRuns(\n stage: Stage,\n { backlog, queue }: FeedingRuntime,\n now: Date,\n): Promise<Release[]> {\n const claimedBefore = new Date(now.getTime() - claimHoldMsOf(stage.spool));\n const entries = await backlog.reclaimStaleClaims(claimedBefore, now);\n const runs = new ItemRuns(queue, stage.spool.name);\n const currentLinks = await runs.currentLinksOf(entries.map(({ _id }) => _id));\n return entries.map((entry, position) => ({\n entry,\n link: currentLinks[position],\n }));\n}\n\nasync function claimWhatTheCeilingAllows(\n stage: Stage,\n backlog: Backlog,\n now: Date,\n): Promise<Release[]> {\n const inFlight = await backlog.countInFlight();\n const room = roomUnderTheCeiling(stage.spool, stage.pace, inFlight);\n const entries = await backlog.claimOldestNeverClaimed(room, now);\n return entries.map((entry) => ({ entry, link: 0 }));\n}\n\nasync function release(\n stage: Stage,\n releases: Release[],\n queue: Queue,\n): Promise<void> {\n if (releases.length === 0) return;\n await queue.addBulk(\n releases.map(({ entry, link }) => ({\n name: stage.jobName,\n data: entry.item,\n opts: {\n ...stage.jobOptions,\n jobId: spoolJobId(stage.spool.name, { itemId: entry._id, link }),\n },\n })),\n );\n}\n","import type { Job, Queue, Worker } from \"bullmq\";\nimport type { ObjectId } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\nimport type { MongoConnection } from \"@/mongo/connection\";\nimport {\n Backlog,\n ItemRuns,\n isALinkOfAnItem,\n itemLinkOf,\n type ItemLink,\n} from \"@/spools\";\n\nimport { willBeRetried } from \"../../job-results-recorder/job-result\";\n\nimport type { StagesByJobName } from \"./stage\";\n\nexport interface ItemRemovalsSettings {\n stages: StagesByJobName;\n queue: Queue;\n connection: MongoConnection;\n logger: Logger;\n}\n\ntype EndedLinksBySpoolName = Map<string, ItemLink[]>;\n\nexport class ItemRemovals {\n private endedLinks: EndedLinksBySpoolName = new Map();\n private removing: Promise<void> | null = null;\n\n constructor(private readonly settings: ItemRemovalsSettings) {}\n\n listenTo(worker: Worker): void {\n worker.on(\"completed\", (job) => this.noteTheEndOf(job));\n worker.on(\"failed\", (job) => {\n if (job === undefined || willBeRetried(job)) return;\n this.noteTheEndOf(job);\n });\n }\n\n async waitForRemovalsInProgress(): Promise<void> {\n while (this.removing) await this.removing;\n }\n\n private noteTheEndOf(job: Job): void {\n const stage = this.settings.stages.get(job.name);\n if (stage === undefined) return;\n const jobId = String(job.id);\n if (!isALinkOfAnItem(stage.spool.name, jobId)) return;\n\n this.addToEndedLinks(stage.spool.name, itemLinkOf(stage.spool.name, jobId));\n this.removing ??= this.removeTheItemsWhoseRunEnded();\n }\n\n private addToEndedLinks(spoolName: string, endedLink: ItemLink): void {\n const endedLinks = this.endedLinks.get(spoolName) ?? [];\n endedLinks.push(endedLink);\n this.endedLinks.set(spoolName, endedLinks);\n }\n\n private async removeTheItemsWhoseRunEnded(): Promise<void> {\n while (this.endedLinks.size > 0) {\n const batch = this.endedLinks;\n this.endedLinks = new Map();\n await Promise.all(\n [...batch].map(([spoolName, endedLinks]) =>\n this.removeWhereTheRunEnded(spoolName, endedLinks),\n ),\n );\n }\n this.removing = null;\n }\n\n private async removeWhereTheRunEnded(\n spoolName: string,\n endedLinks: ItemLink[],\n ): Promise<void> {\n try {\n const itemIds = await this.itemsWhoseRunEnded(spoolName, endedLinks);\n await new Backlog(spoolName, this.settings.connection).removeAll(itemIds);\n await new ItemRuns(this.settings.queue, spoolName).forget(itemIds);\n } catch (error) {\n this.warnOfItemsLeftBehind(spoolName, endedLinks, error);\n }\n }\n\n private async itemsWhoseRunEnded(\n spoolName: string,\n endedLinks: ItemLink[],\n ): Promise<ObjectId[]> {\n const runs = new ItemRuns(this.settings.queue, spoolName);\n const currentLinks = await runs.currentLinksOf(\n endedLinks.map(({ itemId }) => itemId),\n );\n return endedLinks\n .filter(({ link }, position) => currentLinks[position] <= link)\n .map(({ itemId }) => itemId);\n }\n\n private warnOfItemsLeftBehind(\n spoolName: string,\n endedLinks: ItemLink[],\n error: unknown,\n ): void {\n this.settings.logger.warn(\n { err: error, itemIds: endedLinks.map(({ itemId }) => String(itemId)) },\n `[ravenflow] ${endedLinks.length} links of the spool \"${spoolName}\" ended, but their items could not be removed from its backlog: they stay in it, and are released again ten ticks after their claim.`,\n );\n }\n}\n","import type { JobsOptions } from \"bullmq\";\nimport {\n isSpoolFed,\n type AnyJob,\n type PacePolicy,\n type SpoolTrigger,\n} from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\n\nexport interface Stage {\n jobName: string;\n spool: SpoolTrigger;\n pace: PacePolicy;\n jobOptions: JobsOptions;\n}\n\nexport type StagesByJobName = Map<string, Stage>;\n\nexport function stagesOf(jobs: Record<string, AnyJob>): StagesByJobName {\n return new Map(\n Object.entries(jobs).flatMap(([jobName, job]) =>\n stageEntriesOf(jobName, job),\n ),\n );\n}\n\nfunction stageEntriesOf(jobName: string, job: AnyJob): Array<[string, Stage]> {\n if (!isSpoolFed(job)) return [];\n const { trigger, pace } = job;\n const jobOptions = buildJobOptions(job);\n return [[jobName, { jobName, spool: trigger.spool, pace, jobOptions }]];\n}\n","import type { Queue } from \"bullmq\";\nimport { tickMsOf } from \"@/spools\";\n\nimport type { Stage, StagesByJobName } from \"./stage\";\n\nconst TICKS_KEPT = 100;\n\nexport async function reconcileTicks(\n feederQueue: Queue,\n stages: StagesByJobName,\n): Promise<void> {\n await removeTicksOfUndeclaredStages(feederQueue, stages);\n await Promise.all(\n [...stages.values()].map((stage) => scheduleTicks(feederQueue, stage)),\n );\n}\n\nasync function removeTicksOfUndeclaredStages(\n feederQueue: Queue,\n stages: StagesByJobName,\n): Promise<void> {\n const schedulers = await feederQueue.getJobSchedulers();\n const undeclared = schedulers.filter(({ key }) => !stages.has(key));\n await Promise.all(\n undeclared.map(({ key }) => feederQueue.removeJobScheduler(key)),\n );\n}\n\nasync function scheduleTicks(feederQueue: Queue, stage: Stage): Promise<void> {\n await feederQueue.upsertJobScheduler(\n stage.jobName,\n { every: tickMsOf(stage.spool) },\n {\n name: stage.jobName,\n opts: {\n removeOnComplete: { count: TICKS_KEPT },\n removeOnFail: { count: TICKS_KEPT },\n },\n },\n );\n}\n","import {\n Queue,\n Worker,\n type ConnectionOptions as RedisConnectionOptions,\n type Job,\n} from \"bullmq\";\nimport type { ControlReads } from \"@/control-plane\";\nimport type { AnyJob } from \"@/job\";\nimport type { Logger } from \"@/logger\";\nimport { MongoConnection } from \"@/mongo/connection\";\nimport { Backlog } from \"@/spools\";\n\nimport { logBullmqErrors } from \"../../log-bullmq-errors\";\nimport { waitOrCutShort } from \"../../mongodb-deadline-on-close\";\n\nimport { feedSpool } from \"./feed-spool\";\nimport { ItemRemovals } from \"./item-removals\";\nimport { stagesOf, type StagesByJobName } from \"./stage\";\nimport { reconcileTicks } from \"./ticks\";\n\nconst FEEDER_QUEUE_PREFIX = \"rav-internal-feed-spools-\";\n\nconst ONE_TICK_AT_A_TIME = 1;\n\nexport interface SpoolFeederSettings {\n redis: RedisConnectionOptions;\n mongo: string;\n queue: Queue;\n controls: ControlReads;\n jobs: Record<string, AnyJob>;\n logger: Logger;\n}\n\ninterface Feeding {\n feederQueue: Queue;\n tickWorker: Worker;\n}\n\nexport class SpoolFeeder {\n private readonly stages: StagesByJobName;\n private readonly connection: MongoConnection;\n private readonly itemRemovals: ItemRemovals;\n private readonly indexedBacklogs = new Set<string>();\n private feeding: Feeding | null = null;\n\n constructor(private readonly settings: SpoolFeederSettings) {\n this.stages = stagesOf(settings.jobs);\n this.connection = new MongoConnection(settings.mongo);\n this.itemRemovals = new ItemRemovals({\n stages: this.stages,\n queue: settings.queue,\n connection: this.connection,\n logger: settings.logger,\n });\n }\n\n async open(worker: Worker): Promise<void> {\n if (this.stages.size === 0) return;\n const feederQueue = new Queue(feederQueueNameOf(this.settings.queue), {\n connection: this.settings.redis,\n });\n logBullmqErrors(feederQueue, this.settings.logger);\n const tickWorker = this.openTickWorker(feederQueue.name);\n this.feeding = { feederQueue, tickWorker };\n this.itemRemovals.listenTo(worker);\n await feederQueue.setGlobalConcurrency(ONE_TICK_AT_A_TIME);\n await reconcileTicks(feederQueue, this.stages);\n }\n\n async stopTicking(): Promise<void> {\n const feeding = this.feeding;\n this.feeding = null;\n if (!feeding) return;\n\n await waitOrCutShort(feeding.tickWorker.close(), () =>\n this.connection.close(),\n );\n await feeding.feederQueue.close();\n }\n\n async finishTheRemovals(): Promise<void> {\n await waitOrCutShort(this.itemRemovals.waitForRemovalsInProgress(), () =>\n this.connection.close(),\n );\n }\n\n async close(): Promise<void> {\n await this.stopTicking();\n await this.finishTheRemovals();\n await this.connection.close();\n }\n\n private openTickWorker(feederQueueName: string): Worker {\n const worker = new Worker(feederQueueName, (tick) => this.tick(tick), {\n connection: this.settings.redis,\n });\n worker.on(\"failed\", (tick, error) => this.warnOfAFailedTick(tick, error));\n logBullmqErrors(worker, this.settings.logger);\n return worker;\n }\n\n private async tick(tick: Job): Promise<void> {\n const stage = this.stages.get(tick.name);\n if (stage === undefined) throw this.undeclaredSpoolError(tick);\n const backlog = new Backlog(stage.spool.name, this.connection);\n await this.indexOnce(backlog);\n await feedSpool(stage, {\n backlog,\n queue: this.settings.queue,\n controls: this.settings.controls,\n logger: this.settings.logger,\n });\n }\n\n private async indexOnce(backlog: Backlog): Promise<void> {\n if (this.indexedBacklogs.has(backlog.spoolName)) return;\n await backlog.indexForTheClaim();\n this.indexedBacklogs.add(backlog.spoolName);\n }\n\n private undeclaredSpoolError(tick: Job): Error {\n return new Error(\n `[ravenflow] no spool of \"${this.settings.queue.name}\" feeds \"${tick.name}\": its config does not declare one.`,\n );\n }\n\n private warnOfAFailedTick(tick: Job | undefined, error: Error): void {\n this.settings.logger.warn(\n { err: error },\n `[ravenflow] a tick of the spool feeding \"${tick?.name}\" failed; the next one releases what it did not.`,\n );\n }\n}\n\nfunction feederQueueNameOf(queue: Queue): string {\n return `${FEEDER_QUEUE_PREFIX}${queue.name}`;\n}\n","import { MetricsTime, Worker } from \"bullmq\";\n\nimport { routeByName, type RouterRuntime } from \"./job-router\";\nimport { logBullmqErrors } from \"./log-bullmq-errors\";\nimport type { RavenflowWorkerOptions } from \"./types\";\n\nconst DEFAULT_CONCURRENCY = 5;\n\nexport type WorkerRuntime = Omit<RouterRuntime, \"shutdown\">;\n\nexport function openWorker(\n options: RavenflowWorkerOptions,\n runtime: WorkerRuntime,\n): Worker {\n const shutdown = new AbortController();\n const route = routeByName({ ...runtime, shutdown: shutdown.signal });\n const worker = new Worker(options.queue, route, {\n connection: options.redis,\n concurrency: options.concurrency ?? DEFAULT_CONCURRENCY,\n metrics: { maxDataPoints: MetricsTime.ONE_WEEK },\n autorun: false,\n });\n abortWhenClosing(worker, shutdown);\n logBullmqErrors(worker, runtime.logger);\n return worker;\n}\n\nfunction abortWhenClosing(worker: Worker, shutdown: AbortController): void {\n worker.once(\"closing\", () => {\n shutdown.abort(new Error(\"[ravenflow] the worker is shutting down\"));\n });\n}\n","import { MongoClient, type TopologyDescriptionChangedEvent } from \"mongodb\";\nimport type { Logger } from \"@/logger\";\n\nconst THE_DRIVERS_RECOVERY_LAG_MS = 10_000;\n\nexport interface MongoWatchSettings {\n mongo: string;\n gracePeriodMs: number;\n logger: Logger;\n onDurableLoss: (unreachableForMs: number) => void;\n}\n\nexport class MongoWatch {\n private readonly client: MongoClient;\n private unreachableSince = 0;\n private graceTimer: ReturnType<typeof setTimeout> | null = null;\n private answeredOnce = false;\n\n constructor(private readonly settings: MongoWatchSettings) {\n this.client = new MongoClient(settings.mongo, {\n serverSelectionTimeoutMS:\n settings.gracePeriodMs + THE_DRIVERS_RECOVERY_LAG_MS,\n });\n }\n\n open(): void {\n this.client.on(\"topologyDescriptionChanged\", this.onTopologyChange);\n this.startTheGracePeriod();\n this.client.connect().catch((error: unknown) => this.noteItGaveUp(error));\n }\n\n async close(): Promise<void> {\n this.client.off(\"topologyDescriptionChanged\", this.onTopologyChange);\n this.stopTheGracePeriod();\n await this.client.close();\n }\n\n private readonly onTopologyChange = (\n event: TopologyDescriptionChangedEvent,\n ): void => {\n if (!event.newDescription.hasDataBearingServers) {\n this.noteUnreachable();\n return;\n }\n this.noteReachable();\n };\n\n private noteUnreachable(): void {\n if (this.graceTimer !== null) return;\n this.warnOfALoss();\n this.startTheGracePeriod();\n }\n\n private noteReachable(): void {\n if (this.graceTimer === null) return;\n if (this.answeredOnce) this.sayItIsBack();\n this.answeredOnce = true;\n this.stopTheGracePeriod();\n }\n\n private startTheGracePeriod(): void {\n this.unreachableSince = Date.now();\n this.graceTimer = setTimeout(\n () => this.settings.onDurableLoss(Date.now() - this.unreachableSince),\n this.settings.gracePeriodMs,\n );\n }\n\n private stopTheGracePeriod(): void {\n if (this.graceTimer === null) return;\n clearTimeout(this.graceTimer);\n this.graceTimer = null;\n }\n\n private noteItGaveUp(error: unknown): void {\n this.settings.logger.debug(\n { err: error },\n \"[ravenflow] the worker's watch on MongoDB stopped trying to connect.\",\n );\n }\n\n private warnOfALoss(): void {\n this.settings.logger.warn(\n { gracePeriodMs: this.settings.gracePeriodMs },\n \"[ravenflow] MongoDB is unreachable: the worker withdraws if it stays so for its whole grace period.\",\n );\n }\n\n private sayItIsBack(): void {\n this.settings.logger.info(\n { outageMs: Date.now() - this.unreachableSince },\n \"[ravenflow] MongoDB is reachable again, within the worker's grace period.\",\n );\n }\n}\n","import type { Logger } from \"@/logger\";\n\nconst EXIT_CODE_OF_A_WITHDRAWAL = 1;\n\nexport interface WithdrawingWorker {\n queue: string;\n logger: Logger;\n onWithdraw?: (reason: string) => void | Promise<void>;\n close: () => Promise<void>;\n}\n\nexport async function withdraw(\n worker: WithdrawingWorker,\n unreachableForMs: number,\n): Promise<void> {\n const reason = reasonOf(unreachableForMs);\n sayItWithdraws(worker, reason);\n await closeTheWorker(worker);\n process.exitCode = EXIT_CODE_OF_A_WITHDRAWAL;\n sayItHasWithdrawn(worker, reason);\n await callOnWithdraw(worker, reason);\n}\n\nfunction reasonOf(unreachableForMs: number): string {\n return `MongoDB has been unreachable for ${Math.round(unreachableForMs / 1_000)}s`;\n}\n\nfunction sayItWithdraws({ queue, logger }: WithdrawingWorker, reason: string) {\n logger.fatal(\n { reason },\n `[ravenflow] the worker serving \"${queue}\" withdraws: ${reason}. It takes no new job, and finishes the ones it holds.`,\n );\n}\n\nasync function closeTheWorker({\n queue,\n logger,\n close,\n}: WithdrawingWorker): Promise<void> {\n try {\n await close();\n } catch (error) {\n logger.error(\n { err: error },\n `[ravenflow] the worker serving \"${queue}\" could not close all it opened; it withdraws all the same.`,\n );\n }\n}\n\nfunction sayItHasWithdrawn(\n { queue, logger }: WithdrawingWorker,\n reason: string,\n) {\n logger.warn(\n { reason },\n `[ravenflow] the worker serving \"${queue}\" has withdrawn, and closed: the process exits with code ${EXIT_CODE_OF_A_WITHDRAWAL} once nothing else holds it.`,\n );\n}\n\nasync function callOnWithdraw(\n { logger, onWithdraw }: WithdrawingWorker,\n reason: string,\n): Promise<void> {\n try {\n await onWithdraw?.(reason);\n } catch (error) {\n logger.error(\n { err: error },\n \"[ravenflow] onWithdraw threw; the withdrawal itself stands.\",\n );\n }\n}\n","import type { Queue } from \"bullmq\";\nimport {\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n DEFAULT_GRACE_PERIOD_MS,\n DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n} from \"@/config/constants\";\nimport { openQueue } from \"@/queues\";\n\nimport { ControlPlaneReader } from \"./control-plane-reader\";\nimport { JobResultsAggregator } from \"./internal-jobs/job-results-aggregator\";\nimport { SpoolFeeder } from \"./internal-jobs/spool-feeder\";\nimport { JobResultsRecorder } from \"./job-results-recorder\";\nimport { logBullmqErrors } from \"./log-bullmq-errors\";\nimport { openWorker } from \"./open-worker\";\nimport type { Serving } from \"./serving\";\nimport type { WorkerSettings } from \"./types\";\nimport { MongoWatch, type MongoWatchSettings } from \"./withdrawal\";\n\nexport function openServing(\n settings: WorkerSettings,\n onDurableLoss: MongoWatchSettings[\"onDurableLoss\"],\n): Serving {\n const { config, options, jobs, logger } = settings;\n const queue = openQueue(options.queue, {\n connection: options.redis,\n retention: config.queuesRetention,\n });\n logBullmqErrors(queue, logger);\n const controlPlaneReader = buildControlPlaneReader(settings);\n const jobResultsRecorder = buildJobResultsRecorder(settings, queue);\n const worker = openWorker(options, {\n jobs,\n logger,\n queue,\n controls: controlPlaneReader,\n jobResultsRecorder,\n });\n return {\n queue,\n controlPlaneReader,\n jobResultsRecorder,\n jobResultsAggregator: buildJobResultsAggregator(settings),\n spoolFeeder: buildSpoolFeeder(settings, { queue, controlPlaneReader }),\n mongoWatch: buildMongoWatch(settings, onDurableLoss),\n worker,\n };\n}\n\nfunction buildControlPlaneReader({\n options,\n logger,\n}: WorkerSettings): ControlPlaneReader {\n return new ControlPlaneReader({\n redis: options.redis,\n mongo: options.mongo,\n logger,\n });\n}\n\nfunction buildJobResultsRecorder(\n { config, options, jobs, logger }: WorkerSettings,\n queue: Queue,\n): JobResultsRecorder {\n return new JobResultsRecorder({\n mongo: options.mongo,\n retentionHours:\n config.jobResultsRetentionHours ?? DEFAULT_JOB_RESULTS_RETENTION_HOURS,\n queue,\n jobs,\n logger,\n });\n}\n\nfunction buildJobResultsAggregator({\n config,\n options,\n logger,\n}: WorkerSettings): JobResultsAggregator {\n return new JobResultsAggregator({\n redis: options.redis,\n mongo: options.mongo,\n retentionHours:\n config.aggregatedResultsRetentionHours ??\n DEFAULT_AGGREGATED_RESULTS_RETENTION_HOURS,\n logger,\n });\n}\n\nfunction buildSpoolFeeder(\n { options, jobs, logger }: WorkerSettings,\n { queue, controlPlaneReader }: Pick<Serving, \"queue\" | \"controlPlaneReader\">,\n): SpoolFeeder {\n return new SpoolFeeder({\n redis: options.redis,\n mongo: options.mongo,\n queue,\n controls: controlPlaneReader,\n jobs,\n logger,\n });\n}\n\nfunction buildMongoWatch(\n { options, logger }: WorkerSettings,\n onDurableLoss: MongoWatchSettings[\"onDurableLoss\"],\n): MongoWatch {\n return new MongoWatch({\n mongo: options.mongo,\n gracePeriodMs: options.withdrawal?.afterMs ?? DEFAULT_GRACE_PERIOD_MS,\n logger,\n onDurableLoss,\n });\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport { declaredQueueNames } from \"@/queues\";\n\nexport function refuseAQueueItsConfigDoesNotDeclare(\n queue: string,\n config: RavenflowConfig,\n): void {\n const declared = declaredQueueNames(config);\n if (declared.includes(queue)) return;\n\n const quoted = declared.map((name) => `\"${name}\"`).join(\", \");\n throw new Error(\n `[ravenflow] no job of this config runs on \"${queue}\": its queues are ${quoted}.`,\n );\n}\n","export function describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import {\n isRedisInstance,\n type ConnectionOptions as RedisConnectionOptions,\n type RedisOptions,\n} from \"bullmq\";\nimport { isSpoolFed, type AnyJob, type AnySpoolFedJob } from \"@/job\";\nimport { inFlightCeilingOf } from \"@/spools\";\n\nimport type { JobResultsRecorderOpening } from \"./job-results-recorder\";\nimport type { SchedulerChanges } from \"./schedulers\";\n\nconst RAVENFLOW = `\n ██████╗ █████╗ ██╗ ██╗███████╗███╗ ██╗███████╗██╗ ██████╗ ██╗ ██╗\n ██╔══██╗██╔══██╗██║ ██║██╔════╝████╗ ██║██╔════╝██║ ██╔═══██╗██║ ██║\n ██████╔╝███████║██║ ██║█████╗ ██╔██╗ ██║█████╗ ██║ ██║ ██║██║ █╗ ██║\n ██╔══██╗██╔══██║╚██╗ ██╔╝██╔══╝ ██║╚██╗██║██╔══╝ ██║ ██║ ██║██║███╗██║\n ██║ ██║██║ ██║ ╚████╔╝ ███████╗██║ ╚████║██║ ███████╗╚██████╔╝╚███╔███╔╝\n ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝\n`;\n\nconst RULE = \"═\".repeat(85);\n\nconst FEEDS_IN_ORDER = [\"nothing\", \"clock\", \"spool\"] as const;\n\ninterface Feed {\n kind: (typeof FEEDS_IN_ORDER)[number];\n label: string;\n}\n\nexport interface BannerFacts {\n queue: string;\n concurrency: number;\n redis: RedisConnectionOptions;\n mongo: string;\n recorderOpening: JobResultsRecorderOpening;\n jobs: Record<string, AnyJob>;\n schedulers: SchedulerChanges;\n}\n\nexport function printBanner(facts: BannerFacts): void {\n console.log(\n [\n RAVENFLOW,\n RULE,\n \"[Config]\",\n ...configLines(facts),\n \"\",\n \"[Registered Jobs]\",\n ...registeredJobLines(facts.jobs),\n \"\",\n \"[Scheduled Jobs]\",\n ...schedulerLines(facts.schedulers),\n RULE,\n \"Ready to process jobs...\",\n ].join(\"\\n\"),\n );\n}\n\nfunction configLines(facts: BannerFacts): string[] {\n return [\n ` -> queue: ${facts.queue}`,\n ` -> concurrency: ${facts.concurrency}`,\n ` -> redis: ${addressOf(facts.redis)}`,\n ` -> mongo: ${mongoLineOf(facts)}`,\n ];\n}\n\nfunction addressOf(redis: RedisConnectionOptions): string {\n if (isRedisInstance(redis)) return \"an ioredis client\";\n\n const {\n url,\n host = \"localhost\",\n port = 6379,\n db = 0,\n } = redis as RedisOptions;\n return url ? withoutPassword(url) : `${host}:${port}/${db}`;\n}\n\nfunction mongoLineOf({ mongo, recorderOpening }: BannerFacts): string {\n const address = withoutPassword(mongo);\n if (!recorderOpening.opened) {\n return `${address} (job results are not recorded: ${recorderOpening.because})`;\n }\n return address;\n}\n\nfunction withoutPassword(uri: string): string {\n return uri.replace(/\\/\\/([^:/@]*):[^@]*@/, \"//$1:***@\");\n}\n\nfunction registeredJobLines(jobs: Record<string, AnyJob>): string[] {\n const lines = Object.entries(jobs)\n .map(([name, job]) => ({ name, feed: feedOf(job) }))\n .sort((a, b) => feedRank(a.feed) - feedRank(b.feed))\n .map(({ name, feed }) => ` . ${name}${feed.label}`);\n return lines.length > 0 ? lines : [\" (none)\"];\n}\n\nfunction feedOf(job: AnyJob): Feed {\n const cron = job.trigger?.cron;\n if (cron) return { kind: \"clock\", label: ` (↻ ${cron})` };\n if (isSpoolFed(job)) return { kind: \"spool\", label: spoolLabelOf(job) };\n return { kind: \"nothing\", label: \"\" };\n}\n\nfunction spoolLabelOf({ trigger, pace }: AnySpoolFedJob): string {\n const ceiling = inFlightCeilingOf(trigger.spool, pace);\n return ` (← ${trigger.spool.name}, ${ceiling} in flight at most)`;\n}\n\nfunction feedRank(feed: Feed): number {\n return FEEDS_IN_ORDER.indexOf(feed.kind);\n}\n\nfunction schedulerLines(changes: SchedulerChanges): string[] {\n const lines = [\n ...changes.added.map(({ name, pattern }) => ` + ${name} → ${pattern}`),\n ...changes.rescheduled.map(\n ({ name, pattern, previousPattern }) =>\n ` ↻ ${name} → ${pattern} (was ${previousPattern})`,\n ),\n ...changes.removed.map((name) => ` - ${name}`),\n ];\n return lines.length > 0 ? lines : [\" (no change)\"];\n}\n","import type { JobSchedulerTemplateOptions, Queue } from \"bullmq\";\nimport { describeError } from \"@/describe-error\";\nimport type { AnyJob } from \"@/job\";\nimport { buildJobOptions } from \"@/queues\";\n\nexport interface CronSchedule {\n name: string;\n pattern: string;\n options: JobSchedulerTemplateOptions;\n}\n\nexport interface Rescheduled extends CronSchedule {\n previousPattern: string;\n}\n\nexport interface SchedulerChanges {\n added: CronSchedule[];\n rescheduled: Rescheduled[];\n removed: string[];\n}\n\ntype PatternsByScheduler = Map<string, string>;\n\nexport async function reconcileSchedulers(\n queue: Queue,\n jobs: Record<string, AnyJob>,\n): Promise<SchedulerChanges> {\n const declared = cronSchedulesOf(jobs);\n const existing = await patternsByScheduler(queue);\n const changes = changesBetween(declared, existing);\n\n await Promise.all(\n changes.removed.map((key) => queue.removeJobScheduler(key)),\n );\n await Promise.all(declared.map((schedule) => upsert(queue, schedule)));\n return changes;\n}\n\nfunction cronSchedulesOf(jobs: Record<string, AnyJob>): CronSchedule[] {\n return Object.entries(jobs).flatMap(([name, job]) => {\n const pattern = job.trigger?.cron;\n if (pattern === undefined) return [];\n return [{ name, pattern, options: buildJobOptions(job) }];\n });\n}\n\nasync function patternsByScheduler(queue: Queue): Promise<PatternsByScheduler> {\n const schedulers = await queue.getJobSchedulers();\n return new Map(\n schedulers.map(({ key, pattern }) => [key, pattern ?? \"no pattern\"]),\n );\n}\n\nfunction changesBetween(\n declared: CronSchedule[],\n existing: PatternsByScheduler,\n): SchedulerChanges {\n const declaredNames = new Set(declared.map(({ name }) => name));\n return {\n added: declared.filter(({ name }) => !existing.has(name)),\n rescheduled: declared.flatMap((schedule) =>\n reschedulingOf(schedule, existing),\n ),\n removed: [...existing.keys()].filter((key) => !declaredNames.has(key)),\n };\n}\n\nfunction reschedulingOf(\n schedule: CronSchedule,\n existing: PatternsByScheduler,\n): Rescheduled[] {\n const previousPattern = existing.get(schedule.name);\n if (previousPattern === undefined) return [];\n if (previousPattern === schedule.pattern) return [];\n return [{ ...schedule, previousPattern }];\n}\n\nasync function upsert(\n queue: Queue,\n { name, pattern, options }: CronSchedule,\n): Promise<void> {\n try {\n await queue.upsertJobScheduler(name, { pattern }, { name, opts: options });\n } catch (error) {\n throw new Error(\n `[ravenflow] \"${name}\" could not be scheduled on \"${pattern}\": ${describeError(error)}`,\n );\n }\n}\n","import type { Queue, Worker } from \"bullmq\";\nimport { describeError } from \"@/describe-error\";\n\nimport { printBanner } from \"./banner\";\nimport type { ControlPlaneReader } from \"./control-plane-reader\";\nimport type { JobResultsAggregator } from \"./internal-jobs/job-results-aggregator\";\nimport type { SpoolFeeder } from \"./internal-jobs/spool-feeder\";\nimport type {\n JobResultsRecorder,\n JobResultsRecorderOpening,\n} from \"./job-results-recorder\";\nimport { reconcileSchedulers } from \"./schedulers\";\nimport type { WorkerSettings } from \"./types\";\nimport type { MongoWatch } from \"./withdrawal\";\n\nexport interface Serving {\n queue: Queue;\n controlPlaneReader: ControlPlaneReader;\n jobResultsRecorder: JobResultsRecorder;\n jobResultsAggregator: JobResultsAggregator;\n spoolFeeder: SpoolFeeder;\n mongoWatch: MongoWatch;\n worker: Worker;\n}\n\nexport async function serve(\n serving: Serving,\n settings: WorkerSettings,\n): Promise<void> {\n const { options, jobs } = settings;\n const { queue, worker } = serving;\n serving.mongoWatch.open();\n await serving.controlPlaneReader.open();\n const recorderOpening = await openRecorder(serving, settings);\n await serving.jobResultsAggregator.open();\n await serving.spoolFeeder.open(worker);\n const schedulers = await reconcileSchedulers(queue, jobs);\n takeJobs(worker, settings);\n await worker.waitUntilReady();\n\n printBanner({\n queue: options.queue,\n concurrency: worker.concurrency,\n redis: options.redis,\n mongo: options.mongo,\n recorderOpening,\n jobs,\n schedulers,\n });\n}\n\nasync function openRecorder(\n { jobResultsRecorder, worker }: Serving,\n settings: WorkerSettings,\n): Promise<JobResultsRecorderOpening> {\n try {\n await jobResultsRecorder.open(worker);\n } catch (error) {\n sayJobResultsAreNotRecorded(settings, error);\n return { opened: false, because: describeError(error) };\n }\n return { opened: true };\n}\n\nfunction sayJobResultsAreNotRecorded(\n { options, logger }: WorkerSettings,\n error: unknown,\n): void {\n logger.error(\n { err: error },\n `[ravenflow] the job results recorder could not start: the worker serves \"${options.queue}\", and its job results are not recorded.`,\n );\n}\n\nfunction takeJobs(worker: Worker, { options, logger }: WorkerSettings): void {\n worker.run().catch((error: unknown) => {\n logger.error(\n { err: error },\n `[ravenflow] the worker serving \"${options.queue}\" stopped taking jobs.`,\n );\n });\n}\n\nexport async function closeInOrder(serving: Serving): Promise<void> {\n await stopWatchingMongoDB(serving);\n await stopTheTicks(serving);\n await stopTheWorker(serving);\n await writeWhatItsJobsLeft(serving);\n await closeTheConnections(serving);\n}\n\nasync function stopWatchingMongoDB(serving: Serving): Promise<void> {\n await serving.mongoWatch.close();\n}\n\nasync function stopTheTicks(serving: Serving): Promise<void> {\n await Promise.all([\n serving.jobResultsAggregator.stopTicking(),\n serving.spoolFeeder.stopTicking(),\n ]);\n}\n\nasync function stopTheWorker(serving: Serving): Promise<void> {\n serving.jobResultsRecorder.stopHoldingJobs();\n await serving.worker.close();\n}\n\nasync function writeWhatItsJobsLeft(serving: Serving): Promise<void> {\n await Promise.all([\n serving.jobResultsRecorder.close(),\n serving.spoolFeeder.finishTheRemovals(),\n ]);\n}\n\nasync function closeTheConnections(serving: Serving): Promise<void> {\n await serving.spoolFeeder.close();\n await serving.jobResultsAggregator.close();\n await serving.controlPlaneReader.close();\n await serving.queue.close();\n}\n","import type { RavenflowConfig } from \"@/config\";\nimport { validateConfig } from \"@/config/validate-config\";\nimport { createLogger } from \"@/logger\";\nimport { jobsDeclaredOn } from \"@/queues\";\n\nimport { openServing } from \"./open-serving\";\nimport type { RavenflowWorker } from \"./ravenflow-worker\";\nimport { refuseAQueueItsConfigDoesNotDeclare } from \"./served-queue\";\nimport { closeInOrder, serve, type Serving } from \"./serving\";\nimport type { RavenflowWorkerOptions, WorkerSettings } from \"./types\";\nimport { withdraw, type WithdrawingWorker } from \"./withdrawal\";\n\nexport function createRavenflowWorker(\n config: RavenflowConfig,\n options: RavenflowWorkerOptions,\n): RavenflowWorker {\n validateConfig(config);\n refuseAQueueItsConfigDoesNotDeclare(options.queue, config);\n return workerOf({\n config,\n options,\n jobs: jobsDeclaredOn(options.queue, config),\n logger: createLogger(config.logger),\n });\n}\n\nfunction workerOf(settings: WorkerSettings): RavenflowWorker {\n let serving: Serving | null = null;\n let starting: Promise<void> | null = null;\n let closing: Promise<void> | null = null;\n\n return { start, close };\n\n async function start(): Promise<void> {\n if (serving) throw aSecondStart(settings);\n const opened = openServing(settings, beginAWithdrawal);\n serving = opened;\n starting = serveOrStop(opened);\n try {\n await starting;\n } finally {\n starting = null;\n }\n }\n\n async function close(): Promise<void> {\n await Promise.allSettled([starting]);\n if (serving === null) return;\n closing ??= stopServing(serving);\n await closing;\n }\n\n async function serveOrStop(opened: Serving): Promise<void> {\n try {\n await serve(opened, settings);\n } catch (error) {\n await stopServing(opened);\n throw error;\n }\n }\n\n async function stopServing(opened: Serving): Promise<void> {\n try {\n await closeInOrder(opened);\n } finally {\n serving = null;\n closing = null;\n }\n }\n\n function beginAWithdrawal(unreachableForMs: number): void {\n void withdraw(withdrawingOf(settings, close), unreachableForMs);\n }\n}\n\nfunction aSecondStart({ options }: WorkerSettings): Error {\n return new Error(\n `[ravenflow] this worker has already started on \"${options.queue}\".`,\n );\n}\n\nfunction withdrawingOf(\n { options, logger }: WorkerSettings,\n close: () => Promise<void>,\n): WithdrawingWorker {\n return {\n queue: options.queue,\n logger,\n onWithdraw: options.withdrawal?.onWithdraw,\n close,\n };\n}\n","import { AnyJob } from \"@/job\";\nimport { LoggerOptions } from \"@/logger\";\n\nexport interface RavenflowConfig<TJobs extends string = string> {\n defaultQueue: string;\n jobs: Record<TJobs, AnyJob>;\n\n logger?: LoggerOptions;\n queuesRetention?: QueuesRetentionConfig;\n jobResultsRetentionHours?: number;\n aggregatedResultsRetentionHours?: number;\n}\n\nexport interface QueuesRetentionConfig {\n completedCount?: number;\n failedCount?: number;\n}\n\nexport function defineConfig<const T extends RavenflowConfig>(config: T): T {\n return config;\n}\n"]}