UNPKG

pg-boss

Version:

Queueing jobs in Postgres from Node.js like a boss

470 lines 14.2 kB
export type JobStates = { created: 'created'; retry: 'retry'; active: 'active'; completed: 'completed'; cancelled: 'cancelled'; failed: 'failed'; }; export type Events = { error: 'error'; warning: 'warning'; wip: 'wip'; stopped: 'stopped'; bam: 'bam'; }; export interface IDatabase { executeSql(text: string, values?: unknown[]): Promise<{ rows: any[]; }>; } export interface DatabaseOptions { application_name?: string; database?: string; user?: string; password?: string | (() => string | Promise<string>); host?: string; port?: number; schema?: string; ssl?: any; connectionString?: string; max?: number; db?: IDatabase; connectionTimeoutMillis?: number; } export interface SchedulingOptions { schedule?: boolean; clockMonitorIntervalSeconds?: number; cronWorkerIntervalSeconds?: number; cronMonitorIntervalSeconds?: number; } export interface MaintenanceOptions { supervise?: boolean; migrate?: boolean; createSchema?: boolean; warningSlowQuerySeconds?: number; warningQueueSize?: number; superviseIntervalSeconds?: number; maintenanceIntervalSeconds?: number; queueCacheIntervalSeconds?: number; monitorIntervalSeconds?: number; persistWarnings?: boolean; warningRetentionDays?: number; bamIntervalSeconds?: number; } export interface Migration { release: string; version: number; previous: number; install: string[]; async?: string[]; uninstall?: string[]; } export interface ConstructorOptions extends DatabaseOptions, SchedulingOptions, MaintenanceOptions { __test__enableSpies?: boolean; } export interface ResolvedConstructorOptions extends ConstructorOptions { schema: string; monitorIntervalSeconds: number; cronMonitorIntervalSeconds: number; maintenanceIntervalSeconds: number; bamIntervalSeconds: number; } /** * Options for a queue. All retry, expiration, and retention options set on a * queue will be inherited by each job in the queue unless they are overridden. */ export interface QueueOptions { /** * How many seconds a job may be in active state before being retried or * failed. Must be >=1. The default is 15 minutes. * @default 900 */ expireInSeconds?: number; /** * How many seconds a job may be in created or retry state before it's * deleted. Must be >=1. The default is 14 days. * @default 1209600 */ retentionSeconds?: number; /** * How long a job should be retained in the database after it's completed. Set * to `0` to never delete completed jobs. The default is 7 days. * @default 604800 */ deleteAfterSeconds?: number; /** * Number of times a job is allowed to be retried before it is marked as * failed. * @default 2 */ retryLimit?: number; /** * Delay between retries of failed jobs, in seconds. * @default 0 */ retryDelay?: number; /** * Enables exponential backoff retries based on `retryDelay` instead of a * fixed delay. Sets initial `retryDelay` to 1 if not set. * * A simplified function to get the delay between runs is: `retryDelay * 2 ^ retryCount` * with some jitter. * * The function used to determine the backoff delay is: * ```js * Math.min(retryDelayMax, retryDelay * (2 ** Math.Min(16, retryCount) / 2 + 2 Math.Min(16, retryCount) / 2 * Math.random())) * ``` * @default false */ retryBackoff?: boolean; /** * Maximum delay between retries of failed jobs, in seconds. Only used when * `retryBackoff` is `true`. The default is no limit. */ retryDelayMax?: number; /** * Expected heartbeat interval in seconds. When set, workers must send periodic * heartbeats. If no heartbeat is received within this interval, the monitor will * fail/retry the job. Must be >= 10. NULL = heartbeat disabled (default). */ heartbeatSeconds?: number; } export interface GroupOptions { id: string; tier?: string; } export interface GroupConcurrencyConfig { default: number; tiers?: Record<string, number>; } export interface JobOptions { id?: string; priority?: number; startAfter?: number | string | Date; singletonKey?: string; singletonSeconds?: number; singletonNextSlot?: boolean; keepUntil?: number | string | Date; group?: GroupOptions; deadLetter?: string; } export interface ConnectionOptions { db?: IDatabase; } export interface CompleteOptions extends ConnectionOptions { includeQueued?: boolean; } export interface FindJobsOptions extends ConnectionOptions { id?: string; key?: string; data?: object; queued?: boolean; } export type InsertOptions = ConnectionOptions & { returnId?: boolean; }; export type SendOptions = JobOptions & QueueOptions & ConnectionOptions; /** * The queue policy dictates how jobs are allowed to be queued and processed. * * - `standard` supports all standard features such as deferral, priority, and * throttling. * * - `short` only allows 1 job to be queued, unlimited active. Can be extended * with `singletonKey`. * * - `singleton` only allows 1 job to be active, unlimited queued. Can be * extended with `singletonKey`. * * - `stately` offers a combination of `short` and `singleton`; only allows 1 * job per state, queued and/or active. Can be extended with `singletonKey`. * * - `exclusive` only allows 1 job to be queued or active. Can be extended with * singletonKey`. * * - `key_strict_fifo` ensures strict FIFO ordering per `singletonKey`. Requires * `singletonKey` on every job. Blocks processing of jobs with the same key * while any job with that key is active, in retry, or failed. */ export type QueuePolicy = 'standard' | 'short' | 'singleton' | 'stately' | 'exclusive' | 'key_strict_fifo' | (string & {}); export interface Queue extends QueueOptions { /** * The name of the queue. */ name: string; /** * The policy for the queue. * @default 'standard' */ policy?: QueuePolicy; /** * If set to true, a dedicated table will be created in the partition scheme. * This is more useful for a large queue in order to keep it from being a * "noisy neighbor". * @default false */ partition?: boolean; /** * The name of the queue's dead letter queue. When a job fails after all * retries, the job's payload will be copied into said queue, copying the same * retention and retry configuration as the original job. */ deadLetter?: string; /** * The number of jobs allowed to exist in the created or retry state before * emitting a warning event. */ warningQueueSize?: number; /** * Expected heartbeat interval in seconds for jobs in this queue. * When set, workers must send periodic heartbeats. NULL = heartbeat disabled (default). */ heartbeatSeconds?: number; } export interface QueueResult extends Queue { deferredCount: number; queuedCount: number; activeCount: number; totalCount: number; table: string; createdOn: Date; updatedOn: Date; singletonsActive: string[] | null; } export type ScheduleOptions = SendOptions & { tz?: string; key?: string; }; export interface JobPollingOptions { /** * Interval to check for new jobs, in seconds. Must be >= `0.5` (500 ms). * @default 2 */ pollingIntervalSeconds?: number; } export interface JobFetchOptions { /** * If `true`, all job metadata will be included in the returned job object. * @default false */ includeMetadata?: boolean; /** * Allow jobs with a higher priority to be fetched before jobs with lower or * no priority. * @default true */ priority?: boolean; /** * Fetch jobs in the order they were created. Set to `false` to disable this * sorting and improve performance when the order of jobs does not matter. * @default true */ orderByCreatedOn?: boolean; /** * The number of jobs to fetch. * @default 1 */ batchSize?: number; /** * Fetch jobs even if they have a `startAfter` timestamp in the future. * @default false */ ignoreStartAfter?: boolean; /** * Only fetch jobs with a priority greater than or equal to this value. * Useful for reserving worker capacity exclusively for higher-priority jobs. * Must be an integer. If both `minPriority` and `maxPriority` are set, * `minPriority` must be less than or equal to `maxPriority`. */ minPriority?: number; /** * Only fetch jobs with a priority less than or equal to this value. * Useful for workers dedicated to lower-priority background work. * Must be an integer. If both `minPriority` and `maxPriority` are set, * `minPriority` must be less than or equal to `maxPriority`. */ maxPriority?: number; } export interface WorkConcurrencyOptions { /** * Number of workers to spawn for this queue (per-node). * Each worker polls and processes jobs independently. */ localConcurrency?: number; /** * Limit concurrent jobs per group within this node (in-memory tracking). * No database overhead. Does not coordinate across nodes. */ localGroupConcurrency?: number | GroupConcurrencyConfig; /** * Limit concurrent jobs per group globally across all nodes (database tracking). * Coordinates across distributed deployments via database queries. */ groupConcurrency?: number | GroupConcurrencyConfig; } export type WorkOptions = JobFetchOptions & JobPollingOptions & WorkConcurrencyOptions & { /** * Custom heartbeat refresh interval in seconds. Defaults to `heartbeatSeconds / 2`. * Must be strictly less than `heartbeatSeconds`. */ heartbeatRefreshSeconds?: number; }; export interface FetchGroupConcurrencyOptions { groupConcurrency?: number | GroupConcurrencyConfig; ignoreGroups?: string[] | null; } export type FetchOptions = JobFetchOptions & ConnectionOptions & FetchGroupConcurrencyOptions; export interface ResolvedWorkOptions extends WorkOptions { pollingInterval: number; } export interface WorkHandler<ReqData, ResData = any> { (job: Job<ReqData>[]): Promise<ResData>; } export interface WorkWithMetadataHandler<ReqData, ResData = any> { (job: JobWithMetadata<ReqData>[]): Promise<ResData>; } export interface Request { name: string; data?: object; options?: SendOptions; } export interface Schedule { name: string; key: string; cron: string; timezone: string; data?: object; options?: SendOptions; } export interface Job<T = object> { id: string; name: string; data: T; expireInSeconds: number; heartbeatSeconds: number | null; signal: AbortSignal; groupId?: string | null; groupTier?: string | null; } export interface JobWithMetadata<T = object> extends Job<T> { priority: number; state: 'created' | 'retry' | 'active' | 'completed' | 'cancelled' | 'failed'; retryLimit: number; retryCount: number; retryDelay: number; retryBackoff: boolean; retryDelayMax?: number; startAfter: Date; startedOn: Date; singletonKey: string | null; singletonOn: Date | null; expireInSeconds: number; deleteAfterSeconds: number; createdOn: Date; completedOn: Date | null; keepUntil: Date; policy: QueuePolicy; heartbeatOn: Date | null; heartbeatSeconds: number | null; deadLetter: string; output: object; } export interface JobInsert<T = object> { id?: string; data?: T; priority?: number; retryLimit?: number; retryDelay?: number; retryBackoff?: boolean; retryDelayMax?: number; startAfter?: number | string | Date; singletonKey?: string; singletonSeconds?: number; expireInSeconds?: number; deleteAfterSeconds?: number; retentionSeconds?: number; heartbeatSeconds?: number; group?: GroupOptions; deadLetter?: string; } export type WorkerState = 'created' | 'active' | 'stopping' | 'stopped'; export interface WipData { id: string; workId: string; name: string; options: WorkOptions; state: WorkerState; count: number; createdOn: number; lastFetchedOn: number | null; lastJobStartedOn: number | null; lastJobEndedOn: number | null; lastJobDuration: number | null; lastError: object | null; lastErrorOn: number | null; } export interface StopOptions { close?: boolean; graceful?: boolean; timeout?: number; } export interface OffWorkOptions { id?: string; wait?: boolean; } export interface EventsMixin extends NodeJS.EventEmitter { events: Record<string, string>; } export interface FunctionsMixin { functions: Function[]; } export type UpdateQueueOptions = Omit<Queue, 'name' | 'partition' | 'policy'>; export interface Warning { message: string; data: object; } export type WarningType = 'slow_query' | 'queue_backlog' | 'clock_skew'; export interface PersistedWarning { id: number; type: WarningType; message: string; data: object; createdOn: Date; } export interface CommandResponse { } export interface BamEntry { id: string; name: string; version: number; status: 'pending' | 'in_progress' | 'completed' | 'failed'; queue?: string; table: string; command: string; error?: string; createdOn: Date; startedOn?: Date; completedOn?: Date; } export interface BamStatusSummary { status: 'pending' | 'in_progress' | 'completed' | 'failed'; count: number; lastCreatedOn: Date; } export interface BamEvent { id: string; name: string; status: string; queue?: string; table: string; error?: string; } export type PgBossEventMap = { error: [error: Error]; warning: [warning: Warning]; wip: [data: WipData[]]; stopped: []; bam: [data: BamEvent]; }; //# sourceMappingURL=types.d.ts.map