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.

49 lines (48 loc) 2.14 kB
import { MultiStepPayload } from "./multi-step-payload.js"; import { none, some } from "scats"; import { TaskStatus } from "./tasks-model.js"; import { TasksWorker } from "./tasks-worker.js"; export class MultiStepTask extends TasksWorker { async handleResolvedChild(payload, activeChild, childTask, context) { context.resolvedChildTask = some(childTask); const nextPayload = payload.copy({ activeChild: none, }); context.setPayload(nextPayload.toJson); if (childTask.status === TaskStatus.finished) { await this.childFinished(nextPayload, childTask, context, activeChild); } else if (childTask.status === TaskStatus.error) { await this.childFailed(nextPayload, childTask, context, activeChild); } else { throw new Error(`Inconsistent workflow state: child task with id=${childTask.id} is not terminal (status=${childTask.status})`); } } async childFinished(payload, _childTask, context, _activeChild) { await this.processNext(payload, context); } async childFailed(payload, childTask, _context, _activeChild) { const childError = childTask.error === undefined ? "Unknown error" : childTask.error; throw new Error(`Child task ${childTask.id} failed: ${childError}`); } async process(payload, context) { const typedPayload = MultiStepPayload.fromJson(payload); await typedPayload.activeChild.match({ some: async (activeChild) => { const childTask = await context.findTask(activeChild.taskId); await childTask.match({ some: async (task) => { await this.handleResolvedChild(typedPayload, activeChild, task, context); }, none: async () => { throw new Error(`Child task with id=${activeChild.taskId} not found`); }, }); }, none: async () => { await this.processNext(typedPayload, context); }, }); } }