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.

69 lines (68 loc) 2.5 kB
import log4js from "log4js"; import { TasksQueueWorker } from "./tasks-queue.worker.js"; import { TasksAuxiliaryWorker } from "./tasks-auxiliary-worker.js"; import { none, some } from "scats"; import { TaskPeriodType, } from "./tasks-model.js"; import { SystemClock } from "./clock.js"; const logger = log4js.getLogger("TasksQueueService"); export class TasksQueueService { tasksQueueDao; clock; poolName; worker; auxiliaryWorker; constructor(tasksQueueDao, manageTasksQueueService, config, clock = new SystemClock(), poolName = "default") { this.tasksQueueDao = tasksQueueDao; this.clock = clock; this.poolName = poolName; this.worker = new TasksQueueWorker(this.tasksQueueDao, config.concurrency, config.loopInterval, this.clock, config.queueNotifier, this.poolName); if (config.runAuxiliaryWorker) { this.auxiliaryWorker = some(new TasksAuxiliaryWorker(tasksQueueDao, manageTasksQueueService, this.clock)); } else { this.auxiliaryWorker = none; } } async schedule(task) { const taskId = await this.tasksQueueDao.schedule(task, this.clock.now()); this.taskScheduled(task.queue); return taskId; } async scheduleAtFixedRate(task) { const taskId = await this.tasksQueueDao.schedulePeriodic(task, TaskPeriodType.fixed_rate, this.clock.now()); this.taskScheduled(task.queue); return taskId; } async scheduleAtFixedDelay(task) { const taskId = await this.tasksQueueDao.schedulePeriodic(task, TaskPeriodType.fixed_delay, this.clock.now()); this.taskScheduled(task.queue); return taskId; } async scheduleAtCron(task) { const taskId = await this.tasksQueueDao.schedulePeriodic(task, TaskPeriodType.cron, this.clock.now()); this.taskScheduled(task.queue); return taskId; } taskScheduled(queueName) { this.worker.tasksScheduled(queueName); } registerWorker(queueName, worker) { this.worker.registerWorker(queueName, worker); } async runOnce() { await this.worker.runOnce(); } start() { try { this.worker.start(); this.auxiliaryWorker.foreach((w) => w.start()); } catch (e) { logger.warn("Failed to process stalled tasks", e); } } async stop() { this.auxiliaryWorker.foreach((w) => w.stop()); await this.worker.stop(); } }