UNPKG

@penkov/tasks_queue

Version:

A lightweight PostgreSQL-backed task queue system with scheduling, retries, backoff strategies, and priority handling. Designed for efficiency and observability in modern Node.js applications.

88 lines (87 loc) 3.22 kB
import { Option } from "scats"; import { ScheduledTask } from "./tasks-model.js"; import { Clock } from "./clock.js"; export interface TasksPipelineState { maxConcurrentTasks: number; tasksInProcess: number; loopRunning: boolean; loopStartedAt: number; lastPollStartedAt: number; lastPollFinishedAt: number; lastSuccessfulPollAt: number; lastPollDurationMs: number; nextLoopTime: number; } /** * Class responsible for polling and processing tasks from a queue. * Tasks are processed concurrently, with a limit on the maximum number of concurrently running tasks. */ export declare class TasksPipeline { private readonly maxConcurrentTasks; private readonly pollNextTask; private readonly peekNextStartAfter; private readonly processTask; private readonly loopInterval; private readonly clock; private readonly poolName; private tasksInProcess; private loopRunning; private nextLoopTime; private periodicTaskFetcher; private stopRequested; private tasksCountListener; private readonly loopTimer; private loopStartedAt; private lastPollStartedAt; private lastPollFinishedAt; private lastSuccessfulPollAt; private lastPollDurationMs; /** * Creates an instance of TasksPipeline. * * @param maxConcurrentTasks Maximum number of tasks to be processed concurrently. * @param pollNextTask A function to fetch the next task to process. * @param peekNextStartAfter a function to fetch next start_after value to reduce sleep time * @param processTask A function that processes a fetched task. * @param loopInterval Interval in milliseconds between polling attempts if no tasks are found. */ constructor(maxConcurrentTasks: number, pollNextTask: () => Promise<Option<ScheduledTask>>, peekNextStartAfter: () => Promise<Option<Date>>, processTask: (t: ScheduledTask) => Promise<void>, loopInterval?: number, clock?: Clock, poolName?: string); /** * Starts the periodic task polling loop. */ start(): void; runOnce(): Promise<void>; getState(): TasksPipelineState; /** * Stops the task polling loop and waits for all running tasks to complete. */ stop(): Promise<void>; /** * Triggers the polling loop immediately if it is not already running. */ triggerLoop(): void; /** * Internal method that performs a single polling loop. * It attempts to fetch and start processing tasks until the maximum number of concurrent tasks is reached. */ private loop; /** * Fetches the next pending task using the poll function and schedules it for processing. * * @returns The next operation to perform in the loop. */ private fetchNextTask; /** * Starts processing a task and handles any errors that might occur. * Once processing is finished, triggers the next polling loop. * * @param t The task to be processed. */ private processTaskInLoop; /** * Marks a task as completed, decreases the number of active tasks and notifies the listener if needed. */ private taskIsDone; private nowMs; private registerMetrics; }