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.

420 lines (419 loc) 12.8 kB
import { __decorate, __metadata } from "tslib"; import { ApiProperty } from "@nestjs/swagger"; import { BackoffType, MissedRunStrategy, TaskPeriodType, TaskStatus, } from "./tasks-model.js"; export class TaskDto { id; parentId; queue; created; initialStart; started; lastHeartbeat; finished; status; missedRunStrategy; priority; error; backoff; backoffType; timeout; name; startAfter; repeatInterval; cronExpression; repeatType; maxAttempts; attempt; payload; result; constructor(id, parentId, queue, created, initialStart, started, lastHeartbeat, finished, status, missedRunStrategy, priority, error, backoff, backoffType, timeout, name, startAfter, repeatInterval, cronExpression, repeatType, maxAttempts, attempt, payload, result) { this.id = id; this.parentId = parentId; this.queue = queue; this.created = created; this.initialStart = initialStart; this.started = started; this.lastHeartbeat = lastHeartbeat; this.finished = finished; this.status = status; this.missedRunStrategy = missedRunStrategy; this.priority = priority; this.error = error; this.backoff = backoff; this.backoffType = backoffType; this.timeout = timeout; this.name = name; this.startAfter = startAfter; this.repeatInterval = repeatInterval; this.cronExpression = cronExpression; this.repeatType = repeatType; this.maxAttempts = maxAttempts; this.attempt = attempt; this.payload = payload; this.result = result; } } export class TasksResult { items; total; constructor(items, total) { this.items = items; this.total = total; } } export var TaskDateSortField; (function (TaskDateSortField) { TaskDateSortField["id"] = "id"; TaskDateSortField["created"] = "created"; TaskDateSortField["initialStart"] = "initial_start"; TaskDateSortField["started"] = "started"; TaskDateSortField["lastHeartbeat"] = "last_heartbeat"; TaskDateSortField["finished"] = "finished"; TaskDateSortField["startAfter"] = "start_after"; })(TaskDateSortField || (TaskDateSortField = {})); export var TaskSortDirection; (function (TaskSortDirection) { TaskSortDirection["asc"] = "asc"; TaskSortDirection["desc"] = "desc"; })(TaskSortDirection || (TaskSortDirection = {})); export class TaskView { id; parentId; queue; created; initialStart; started; lastHeartbeat; finished; status; missedRunStrategy; priority; error; backoff; backoffType; timeout; name; startAfter; repeatInterval; cronExpression; repeatType; maxAttempts; attempt; payload; result; static fromDto(dto) { const res = new TaskView(); res.id = dto.id; res.parentId = dto.parentId.orUndefined; res.queue = dto.queue; res.created = dto.created.getTime(); res.initialStart = dto.initialStart.getTime(); res.started = dto.started.map((d) => d.getTime()).orUndefined; res.lastHeartbeat = dto.lastHeartbeat.map((d) => d.getTime()).orUndefined; res.finished = dto.finished.map((d) => d.getTime()).orUndefined; res.status = dto.status; res.missedRunStrategy = dto.missedRunStrategy; res.priority = dto.priority; res.error = dto.error.orUndefined; res.backoff = dto.backoff; res.backoffType = dto.backoffType; res.timeout = dto.timeout; res.name = dto.name.orUndefined; res.startAfter = dto.startAfter.map((d) => d.getTime()).orUndefined; res.repeatInterval = dto.repeatInterval.orUndefined; res.cronExpression = dto.cronExpression.orUndefined; res.repeatType = dto.repeatType.orUndefined; res.maxAttempts = dto.maxAttempts; res.attempt = dto.attempt; res.payload = dto.payload; res.result = dto.result; return res; } } __decorate([ ApiProperty({ description: "Persistent task id." }), __metadata("design:type", Number) ], TaskView.prototype, "id", void 0); __decorate([ ApiProperty({ required: false, description: "Parent task id for child tasks, if any.", }), __metadata("design:type", Number) ], TaskView.prototype, "parentId", void 0); __decorate([ ApiProperty({ description: "Queue name." }), __metadata("design:type", String) ], TaskView.prototype, "queue", void 0); __decorate([ ApiProperty({ description: "Task creation time as Unix milliseconds." }), __metadata("design:type", Number) ], TaskView.prototype, "created", void 0); __decorate([ ApiProperty({ description: "Original schedule anchor as Unix milliseconds.", }), __metadata("design:type", Number) ], TaskView.prototype, "initialStart", void 0); __decorate([ ApiProperty({ required: false, description: "Current attempt start time as Unix milliseconds, if the task is active.", }), __metadata("design:type", Number) ], TaskView.prototype, "started", void 0); __decorate([ ApiProperty({ required: false, description: "Last heartbeat time as Unix milliseconds, if the task is active and has reported heartbeat.", }), __metadata("design:type", Number) ], TaskView.prototype, "lastHeartbeat", void 0); __decorate([ ApiProperty({ required: false, description: "Finish or retry-transition time as Unix milliseconds, if present.", }), __metadata("design:type", Number) ], TaskView.prototype, "finished", void 0); __decorate([ ApiProperty({ enum: TaskStatus, enumName: "TaskStatus", description: "Current task status.", }), __metadata("design:type", String) ], TaskView.prototype, "status", void 0); __decorate([ ApiProperty({ enum: MissedRunStrategy, enumName: "MissedRunStrategy", description: "Periodic missed-run strategy.", }), __metadata("design:type", String) ], TaskView.prototype, "missedRunStrategy", void 0); __decorate([ ApiProperty({ description: "Queue priority." }), __metadata("design:type", Number) ], TaskView.prototype, "priority", void 0); __decorate([ ApiProperty({ required: false, description: "Last persisted error message, if any.", }), __metadata("design:type", String) ], TaskView.prototype, "error", void 0); __decorate([ ApiProperty({ description: "Base retry backoff in milliseconds." }), __metadata("design:type", Number) ], TaskView.prototype, "backoff", void 0); __decorate([ ApiProperty({ enum: BackoffType, enumName: "BackoffType", description: "Retry backoff formula.", }), __metadata("design:type", String) ], TaskView.prototype, "backoffType", void 0); __decorate([ ApiProperty({ description: "Attempt timeout in milliseconds." }), __metadata("design:type", Number) ], TaskView.prototype, "timeout", void 0); __decorate([ ApiProperty({ required: false, description: "Unique periodic task name, if periodic.", }), __metadata("design:type", String) ], TaskView.prototype, "name", void 0); __decorate([ ApiProperty({ description: "Next eligible start time as Unix milliseconds, if any.", }), __metadata("design:type", Number) ], TaskView.prototype, "startAfter", void 0); __decorate([ ApiProperty({ description: "Repeat interval in milliseconds for interval-based periodic tasks.", }), __metadata("design:type", Number) ], TaskView.prototype, "repeatInterval", void 0); __decorate([ ApiProperty({ description: "Cron expression for cron-based periodic tasks.", }), __metadata("design:type", String) ], TaskView.prototype, "cronExpression", void 0); __decorate([ ApiProperty({ enum: TaskPeriodType, enumName: "TaskPeriodType", description: "Periodic scheduling mode, if any.", }), __metadata("design:type", String) ], TaskView.prototype, "repeatType", void 0); __decorate([ ApiProperty({ description: "Maximum attempts allowed." }), __metadata("design:type", Number) ], TaskView.prototype, "maxAttempts", void 0); __decorate([ ApiProperty({ description: "Persisted attempt counter." }), __metadata("design:type", Number) ], TaskView.prototype, "attempt", void 0); __decorate([ ApiProperty({ description: "Persisted worker input and runtime state." }), __metadata("design:type", Object) ], TaskView.prototype, "payload", void 0); __decorate([ ApiProperty({ required: false, description: "Persisted final result, if any.", }), __metadata("design:type", Object) ], TaskView.prototype, "result", void 0); export class TasksResultView { items; total; } __decorate([ ApiProperty({ type: TaskView, isArray: true, description: "Page items converted to plain task views.", }), __metadata("design:type", Array) ], TasksResultView.prototype, "items", void 0); __decorate([ ApiProperty({ description: "Total number of matching rows before pagination.", }), __metadata("design:type", Number) ], TasksResultView.prototype, "total", void 0); export class QueueStat { queueName; p50; p75; p95; p99; p999; constructor(queueName, p50, p75, p95, p99, p999) { this.queueName = queueName; this.p50 = p50; this.p75 = p75; this.p95 = p95; this.p99 = p99; this.p999 = p999; } } export class TasksCount { queueName; status; count; constructor(queueName, status, count) { this.queueName = queueName; this.status = status; this.count = count; } } export class QueueStatView { queueName; p50; p75; p95; p99; p999; static fromDto(o) { const res = new QueueStatView(); res.queueName = o.queueName; res.p50 = o.p50; res.p75 = o.p75; res.p95 = o.p95; res.p99 = o.p99; res.p999 = o.p999; return res; } } __decorate([ ApiProperty({ description: "Queue name these percentiles belong to." }), __metadata("design:type", String) ], QueueStatView.prototype, "queueName", void 0); __decorate([ ApiProperty({ description: "50th percentile in seconds." }), __metadata("design:type", Number) ], QueueStatView.prototype, "p50", void 0); __decorate([ ApiProperty({ description: "75th percentile in seconds." }), __metadata("design:type", Number) ], QueueStatView.prototype, "p75", void 0); __decorate([ ApiProperty({ description: "95th percentile in seconds." }), __metadata("design:type", Number) ], QueueStatView.prototype, "p95", void 0); __decorate([ ApiProperty({ description: "99th percentile in seconds." }), __metadata("design:type", Number) ], QueueStatView.prototype, "p99", void 0); __decorate([ ApiProperty({ description: "99.9th percentile in seconds." }), __metadata("design:type", Number) ], QueueStatView.prototype, "p999", void 0); export class TasksCountView { queueName; status; count; static fromDto(o) { const res = new TasksCountView(); res.queueName = o.queueName; res.status = o.status; res.count = o.count; return res; } } __decorate([ ApiProperty({ description: "Queue name." }), __metadata("design:type", String) ], TasksCountView.prototype, "queueName", void 0); __decorate([ ApiProperty({ enum: TaskStatus, enumName: "TaskStatus", description: "Task status represented by this count.", }), __metadata("design:type", String) ], TasksCountView.prototype, "status", void 0); __decorate([ ApiProperty({ type: "integer", description: "Number of tasks in this queue/status bucket.", }), __metadata("design:type", Number) ], TasksCountView.prototype, "count", void 0); export class QueuesStat { waitTime; workTime; tasksCount; } __decorate([ ApiProperty({ type: QueueStatView, isArray: true, description: "Queue wait-time percentile stats.", }), __metadata("design:type", Array) ], QueuesStat.prototype, "waitTime", void 0); __decorate([ ApiProperty({ type: QueueStatView, isArray: true, description: "Queue work-time percentile stats.", }), __metadata("design:type", Array) ], QueuesStat.prototype, "workTime", void 0); __decorate([ ApiProperty({ type: TasksCountView, isArray: true, description: "Queue/status task counts.", }), __metadata("design:type", Array) ], QueuesStat.prototype, "tasksCount", void 0);