import { PgBoss } from 'pg-boss'; import { Container } from 'injectkit'; import { JobQueuePolicy } from '../job.queue.policy.js'; import { JobRunner } from '../job.runner.js'; import { PgBossJobRegistryMap } from './pgboss.job.registration.js'; import { Logger } from '@maroonedsoftware/logger'; /** * PgBoss implementation of the {@link JobRunner} interface. * * This runner processes jobs from PostgreSQL queues using pg-boss. It * automatically creates queues for registered jobs, sets up scheduled * jobs, and handles job execution with error logging. * * @example * ```typescript * // Setup * const pgboss = new PgBoss('postgres://...'); * await pgboss.start(); * * const registry = new PgBossJobRegistryMap(); * registry.set('send-email', SendEmailJob); * registry.set('daily-report', { * job: DailyReportJob, * cron: '0 9 * * *' * }); * * const runner = new PgBossJobRunner(container, registry, pgboss, logger); * * // Start processing * await runner.start(); * * // Graceful shutdown * process.on('SIGTERM', async () => { * await runner.stop(); * }); * ``` */ export declare class PgBossJobRunner extends JobRunner { private readonly container; private readonly registrations; private readonly pgboss; private readonly logger; /** * How often, in seconds, a running job polls pg-boss to detect that it has * been cancelled. When a poll observes the job is no longer present or its * state is `cancelled`, the `AbortSignal` passed to the job's handler is * aborted so cooperative handlers can stop. Set to `0` to disable polling * (running jobs will then only be interruptible on shutdown/timeout). * * @default 5 */ cancelPollIntervalSeconds: number; /** * A base {@link JobQueuePolicy} applied to *every* registered queue, beneath * each queue's own policy. Set it to give all queues sane retry/dead-letter * defaults without repeating them on each registration; a field a queue sets * on its own `policy` overrides the same field here. * * Leave it unset (the default) to opt in per queue only. When neither this nor * a queue's own policy supplies any option, that queue is created exactly as * before, with no options passed. * * @default undefined */ defaultQueuePolicy?: JobQueuePolicy; /** * Creates a new PgBossJobRunner instance. * * @param container - The DI container for resolving job instances. * @param registrations - The registry map containing all registered jobs. * @param pgboss - The pg-boss instance to use for queue operations. * @param logger - The logger for recording job execution errors. */ constructor(container: Container, registrations: PgBossJobRegistryMap, pgboss: PgBoss, logger: Logger); /** * Starts the job runner and begins processing registered jobs. * * For each registered job, this method: * 1. Resolves the effective queue policy (the runner's {@link defaultQueuePolicy} * merged with the registration's own policy, if any) * 2. Auto-creates any dead-letter queue the policy references, before the queue * that references it * 3. Creates the queue with the policy's options if it doesn't exist, or updates * an existing queue to match; when no policy applies, the queue is created * with the name only (unchanged pre-policy behavior) * 4. Sets up the cron schedule (for scheduled jobs) * 5. Starts a worker to process jobs from the queue * * Each item in a batch resolves its `Job` instance from the DI container * individually and execution is awaited via `Promise.allSettled`, so pg-boss * does not acknowledge a batch until every job has actually finished and * one job's failure cannot suppress its sibling's logs. * * @returns A promise that resolves when all workers are registered with pg-boss. */ start(): Promise; /** * Merges the runner-wide {@link defaultQueuePolicy} with a registration's own * policy, letting the registration override individual fields. Returns * `undefined` when neither supplies a policy, so a queue with no policy is left * to pg-boss defaults and created exactly as it was before this feature. * * @param registration - The registry entry (a bare identifier or an object). * @returns The effective policy for the queue, or `undefined` if none applies. * @internal */ private resolvePolicy; /** * Ensures a queue exists and, when a policy is supplied, that its retry and * dead-letter options match. Creates the queue (with options) when absent, and * updates an existing queue's options when a policy is given. When no policy * option resolves, an absent queue is created with the name only — byte-for-byte * the pre-policy behavior — and an existing queue is left untouched. * * @param name - The queue name to ensure. * @param policy - The effective policy, or `undefined` for none. * @param ensured - Names already ensured during this start pass (mutated). * @internal */ private ensureQueue; /** * Maps a backend-agnostic {@link JobQueuePolicy} onto pg-boss's native queue * options. Luxon {@link Duration}s become whole-second counts (pg-boss measures * these in seconds). Returns `undefined` when the policy carries no options to * apply, so callers fall back to the name-only create/no-op update path. * * @param policy - The effective policy for a queue. * @returns The pg-boss queue options, or `undefined` if the policy is empty. * @internal */ private toQueueOptions; /** * Polls pg-boss for a running job and aborts the given controller when the job * has been cancelled (or has disappeared, e.g. via {@link PgBossJobBroker.deleteJob}). * * This is what turns {@link PgBossJobBroker.cancel} into a signal the running * handler can observe, even when `cancel` is called from a different process: * the cancellation is a state change on the shared PostgreSQL row, and every * runner polls that row for the jobs it is currently executing. * * @param name - The queue/job name. * @param id - The id of the running job to watch. * @param controller - The controller to abort once cancellation is detected. * @returns A function that stops the poll; always call it when the job finishes. * @internal */ private watchForCancellation; /** * Stops the job runner gracefully. * * This method stops the pg-boss instance, which will: * - Stop accepting new jobs * - Wait for currently executing jobs to complete * - Clean up database connections * * @returns A promise that resolves when the runner has stopped. */ stop(): Promise; } //# sourceMappingURL=pgboss.job.runner.d.ts.map