@workglow/job-queue 0.0.62 → 0.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +9 -4
- package/dist/browser.js.map +3 -3
- package/dist/bun.js +9 -4
- package/dist/bun.js.map +3 -3
- package/dist/job/JobQueueWorker.d.ts.map +1 -1
- package/dist/node.js +9 -4
- package/dist/node.js.map +3 -3
- package/package.json +5 -5
package/dist/browser.js
CHANGED
|
@@ -583,10 +583,14 @@ class JobQueueWorker {
|
|
|
583
583
|
} catch (err) {
|
|
584
584
|
const error = this.normalizeError(err);
|
|
585
585
|
if (error instanceof RetryableJobError) {
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
const currentJob = await this.getJob(job.id);
|
|
587
|
+
if (!currentJob) {
|
|
588
|
+
throw new JobNotFoundError(`Job ${job.id} not found`);
|
|
589
|
+
}
|
|
590
|
+
if (currentJob.runAttempts >= currentJob.maxRetries) {
|
|
591
|
+
await this.failJob(currentJob, new PermanentJobError("Max retries reached"));
|
|
588
592
|
} else {
|
|
589
|
-
await this.rescheduleJob(
|
|
593
|
+
await this.rescheduleJob(currentJob, error.retryDate);
|
|
590
594
|
}
|
|
591
595
|
} else {
|
|
592
596
|
await this.failJob(job, error);
|
|
@@ -666,6 +670,7 @@ class JobQueueWorker {
|
|
|
666
670
|
job.progress = 0;
|
|
667
671
|
job.progressMessage = "";
|
|
668
672
|
job.progressDetails = null;
|
|
673
|
+
job.runAttempts = (job.runAttempts ?? 0) + 1;
|
|
669
674
|
await this.storage.complete(this.classToStorage(job));
|
|
670
675
|
this.events.emit("job_retry", job.id, job.runAfter);
|
|
671
676
|
} catch (err) {
|
|
@@ -1379,4 +1384,4 @@ export {
|
|
|
1379
1384
|
AbortSignalJobError
|
|
1380
1385
|
};
|
|
1381
1386
|
|
|
1382
|
-
//# debugId=
|
|
1387
|
+
//# debugId=93911FFD8A0112A464756E2164756E21
|
package/dist/browser.js.map
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IQueueStorage, JobStatus, JobStorageFormat, QueueChangePayload } from \"@workglow/storage\";\nimport { EventEmitter } from \"@workglow/util\";\nimport { Job } from \"./Job\";\nimport {\n AbortSignalJobError,\n JobDisabledError,\n JobError,\n JobNotFoundError,\n PermanentJobError,\n RetryableJobError,\n} from \"./JobError\";\nimport {\n JobProgressListener,\n JobQueueEventListener,\n JobQueueEventListeners,\n JobQueueEventParameters,\n JobQueueEvents,\n} from \"./JobQueueEventListeners\";\nimport type { JobQueueServer } from \"./JobQueueServer\";\n\n/**\n * Handle returned when submitting a job, providing methods to interact with the job\n */\nexport interface JobHandle<Output> {\n readonly id: unknown;\n waitFor(): Promise<Output>;\n abort(): Promise<void>;\n onProgress(callback: JobProgressListener): () => void;\n}\n\n/**\n * Options for creating a JobQueueClient\n */\nexport interface JobQueueClientOptions<Input, Output> {\n readonly storage: IQueueStorage<Input, Output>;\n readonly queueName: string;\n}\n\n/**\n * Client for submitting jobs and monitoring their progress.\n * Connect to a JobQueueServer for same-process optimization,\n * or use storage subscriptions for cross-process communication.\n */\nexport class JobQueueClient<Input, Output> {\n public readonly queueName: string;\n protected readonly storage: IQueueStorage<Input, Output>;\n protected readonly events = new EventEmitter<JobQueueEventListeners<Input, Output>>();\n protected server: JobQueueServer<Input, Output> | null = null;\n protected storageUnsubscribe: (() => void) | null = null;\n\n /**\n * Map of job IDs to their pending promise resolvers\n */\n protected readonly activeJobPromises: Map<\n unknown,\n Array<{\n resolve: (value: Output) => void;\n reject: (err: JobError) => void;\n }>\n > = new Map();\n\n /**\n * Map of job IDs to their progress listeners\n */\n protected readonly jobProgressListeners: Map<unknown, Set<JobProgressListener>> = new Map();\n\n /**\n * Last known progress state for each job\n */\n protected readonly lastKnownProgress: Map<\n unknown,\n {\n readonly progress: number;\n readonly message: string;\n readonly details: Record<string, unknown> | null;\n }\n > = new Map();\n\n constructor(options: JobQueueClientOptions<Input, Output>) {\n this.queueName = options.queueName;\n this.storage = options.storage;\n }\n\n /**\n * Attach to a local JobQueueServer for same-process event optimization.\n * When attached, events flow directly from server without storage polling.\n */\n public attach(server: JobQueueServer<Input, Output>): void {\n if (this.server) {\n this.detach();\n }\n this.server = server;\n server.addClient(this);\n\n // Unsubscribe from storage if we were using it\n if (this.storageUnsubscribe) {\n this.storageUnsubscribe();\n this.storageUnsubscribe = null;\n }\n }\n\n /**\n * Detach from the current server\n */\n public detach(): void {\n if (this.server) {\n this.server.removeClient(this);\n this.server = null;\n }\n }\n\n /**\n * Connect to storage for cross-process communication (when no local server).\n * Uses storage subscriptions to receive job updates.\n */\n public connect(): void {\n if (this.server) {\n return; // Already connected via server\n }\n\n if (this.storageUnsubscribe) {\n return; // Already subscribed\n }\n\n this.storageUnsubscribe = this.storage.subscribeToChanges(\n (change: QueueChangePayload<Input, Output>) => {\n this.handleStorageChange(change);\n }\n );\n }\n\n /**\n * Disconnect from storage subscriptions\n */\n public disconnect(): void {\n if (this.storageUnsubscribe) {\n this.storageUnsubscribe();\n this.storageUnsubscribe = null;\n }\n this.detach();\n }\n\n /**\n * Submit a job to the queue\n */\n public async submit(\n input: Input,\n options?: {\n readonly jobRunId?: string;\n readonly fingerprint?: string;\n readonly maxRetries?: number;\n readonly runAfter?: Date;\n readonly deadlineAt?: Date;\n }\n ): Promise<JobHandle<Output>> {\n const job: JobStorageFormat<Input, Output> = {\n queue: this.queueName,\n input,\n job_run_id: options?.jobRunId,\n fingerprint: options?.fingerprint,\n max_retries: options?.maxRetries ?? 10,\n run_after: options?.runAfter?.toISOString() ?? new Date().toISOString(),\n deadline_at: options?.deadlineAt?.toISOString() ?? null,\n completed_at: null,\n status: JobStatus.PENDING,\n };\n\n const id = await this.storage.add(job);\n\n return this.createJobHandle(id);\n }\n\n /**\n * Submit multiple jobs to the queue\n */\n public async submitBatch(\n inputs: readonly Input[],\n options?: {\n readonly jobRunId?: string;\n readonly maxRetries?: number;\n }\n ): Promise<readonly JobHandle<Output>[]> {\n const handles: JobHandle<Output>[] = [];\n for (const input of inputs) {\n const handle = await this.submit(input, options);\n handles.push(handle);\n }\n return handles;\n }\n\n /**\n * Get a job by ID\n */\n public async getJob(id: unknown): Promise<Job<Input, Output> | undefined> {\n if (!id) throw new JobNotFoundError(\"Cannot get undefined job\");\n const job = await this.storage.get(id);\n if (!job) return undefined;\n return this.storageToClass(job);\n }\n\n /**\n * Get jobs by run ID\n */\n public async getJobsByRunId(runId: string): Promise<readonly Job<Input, Output>[]> {\n if (!runId) throw new JobNotFoundError(\"Cannot get jobs by undefined runId\");\n const jobs = await this.storage.getByRunId(runId);\n return jobs.map((job) => this.storageToClass(job));\n }\n\n /**\n * Peek at jobs in the queue\n */\n public async peek(status?: JobStatus, num?: number): Promise<readonly Job<Input, Output>[]> {\n const jobs = await this.storage.peek(status, num);\n return jobs.map((job) => this.storageToClass(job));\n }\n\n /**\n * Get the size of the queue\n */\n public async size(status?: JobStatus): Promise<number> {\n return this.storage.size(status);\n }\n\n /**\n * Get the output for an input (if job completed)\n */\n public async outputForInput(input: Input): Promise<Output | null> {\n if (!input) throw new JobNotFoundError(\"Cannot get output for undefined input\");\n return this.storage.outputForInput(input);\n }\n\n /**\n * Wait for a job to complete\n */\n public async waitFor(jobId: unknown): Promise<Output> {\n if (!jobId) throw new JobNotFoundError(\"Cannot wait for undefined job\");\n\n const job = await this.getJob(jobId);\n if (!job) throw new JobNotFoundError(`Job ${jobId} not found`);\n\n if (job.status === JobStatus.COMPLETED) {\n return job.output as Output;\n }\n if (job.status === JobStatus.DISABLED) {\n throw new JobDisabledError(`Job ${jobId} was disabled`);\n }\n if (job.status === JobStatus.FAILED) {\n throw this.buildErrorFromJob(job);\n }\n\n const { promise, resolve, reject } = Promise.withResolvers<Output>();\n promise.catch(() => {}); // Prevent unhandled rejection\n\n const promises = this.activeJobPromises.get(jobId) || [];\n promises.push({ resolve, reject });\n this.activeJobPromises.set(jobId, promises);\n\n return promise;\n }\n\n /**\n * Abort a job\n */\n public async abort(jobId: unknown): Promise<void> {\n if (!jobId) throw new JobNotFoundError(\"Cannot abort undefined job\");\n await this.storage.abort(jobId);\n this.events.emit(\"job_aborting\", this.queueName, jobId);\n }\n\n /**\n * Abort all jobs in a job run\n */\n public async abortJobRun(jobRunId: string): Promise<void> {\n if (!jobRunId) throw new JobNotFoundError(\"Cannot abort job run with undefined jobRunId\");\n const jobs = await this.getJobsByRunId(jobRunId);\n await Promise.allSettled(\n jobs.map((job) => {\n if ([JobStatus.PROCESSING, JobStatus.PENDING].includes(job.status)) {\n return this.abort(job.id);\n }\n })\n );\n }\n\n /**\n * Subscribe to progress updates for a specific job\n */\n public onJobProgress(jobId: unknown, listener: JobProgressListener): () => void {\n if (!this.jobProgressListeners.has(jobId)) {\n this.jobProgressListeners.set(jobId, new Set());\n }\n const listeners = this.jobProgressListeners.get(jobId)!;\n listeners.add(listener);\n\n return () => {\n const listeners = this.jobProgressListeners.get(jobId);\n if (listeners) {\n listeners.delete(listener);\n if (listeners.size === 0) {\n this.jobProgressListeners.delete(jobId);\n }\n }\n };\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n public on<Event extends JobQueueEvents>(\n event: Event,\n listener: JobQueueEventListener<Event>\n ): void {\n this.events.on(event, listener);\n }\n\n public off<Event extends JobQueueEvents>(\n event: Event,\n listener: JobQueueEventListener<Event>\n ): void {\n this.events.off(event, listener);\n }\n\n public once<Event extends JobQueueEvents>(\n event: Event,\n listener: JobQueueEventListener<Event>\n ): void {\n this.events.once(event, listener);\n }\n\n public waitOn<Event extends JobQueueEvents>(\n event: Event\n ): Promise<JobQueueEventParameters<Event, Input, Output>> {\n return this.events.waitOn(event) as Promise<JobQueueEventParameters<Event, Input, Output>>;\n }\n\n // ========================================================================\n // Internal methods called by JobQueueServer for same-process optimization\n // ========================================================================\n\n /**\n * Called by server when a job starts processing\n * @internal\n */\n public handleJobStart(jobId: unknown): void {\n this.lastKnownProgress.set(jobId, {\n progress: 0,\n message: \"\",\n details: null,\n });\n this.events.emit(\"job_start\", this.queueName, jobId);\n }\n\n /**\n * Called by server when a job completes\n * @internal\n */\n public handleJobComplete(jobId: unknown, output: Output): void {\n this.events.emit(\"job_complete\", this.queueName, jobId, output);\n\n const promises = this.activeJobPromises.get(jobId);\n if (promises) {\n promises.forEach(({ resolve }) => resolve(output));\n }\n this.cleanupJob(jobId);\n }\n\n /**\n * Called by server when a job fails\n * @internal\n */\n public handleJobError(jobId: unknown, error: string, errorCode?: string): void {\n this.events.emit(\"job_error\", this.queueName, jobId, error);\n\n const promises = this.activeJobPromises.get(jobId);\n if (promises) {\n const jobError = this.buildErrorFromCode(error, errorCode);\n promises.forEach(({ reject }) => reject(jobError));\n }\n this.cleanupJob(jobId);\n }\n\n /**\n * Called by server when a job is disabled\n * @internal\n */\n public handleJobDisabled(jobId: unknown): void {\n this.events.emit(\"job_disabled\", this.queueName, jobId);\n\n const promises = this.activeJobPromises.get(jobId);\n if (promises) {\n promises.forEach(({ reject }) => reject(new JobDisabledError(\"Job was disabled\")));\n }\n this.cleanupJob(jobId);\n }\n\n /**\n * Called by server when a job is retried\n * @internal\n */\n public handleJobRetry(jobId: unknown, runAfter: Date): void {\n this.events.emit(\"job_retry\", this.queueName, jobId, runAfter);\n }\n\n /**\n * Called by server when job progress updates\n * @internal\n */\n public handleJobProgress(\n jobId: unknown,\n progress: number,\n message: string,\n details: Record<string, unknown> | null\n ): void {\n this.lastKnownProgress.set(jobId, { progress, message, details });\n this.events.emit(\"job_progress\", this.queueName, jobId, progress, message, details);\n\n const listeners = this.jobProgressListeners.get(jobId);\n if (listeners) {\n for (const listener of listeners) {\n listener(progress, message, details);\n }\n }\n }\n\n // ========================================================================\n // Private helpers\n // ========================================================================\n\n private createJobHandle(id: unknown): JobHandle<Output> {\n return {\n id,\n waitFor: () => this.waitFor(id),\n abort: () => this.abort(id),\n onProgress: (callback: JobProgressListener) => this.onJobProgress(id, callback),\n };\n }\n\n private cleanupJob(jobId: unknown): void {\n this.activeJobPromises.delete(jobId);\n this.lastKnownProgress.delete(jobId);\n this.jobProgressListeners.delete(jobId);\n }\n\n private handleStorageChange(change: QueueChangePayload<Input, Output>): void {\n if (!change.new && !change.old) return;\n\n const jobId = change.new?.id ?? change.old?.id;\n if (!jobId) return;\n\n // Only process changes for our queue\n const queueName = change.new?.queue ?? change.old?.queue;\n if (queueName !== this.queueName) return;\n\n if (change.type === \"UPDATE\" && change.new) {\n const newStatus = change.new.status;\n const oldStatus = change.old?.status;\n\n if (newStatus === JobStatus.PROCESSING && oldStatus === JobStatus.PENDING) {\n this.handleJobStart(jobId);\n } else if (newStatus === JobStatus.COMPLETED) {\n this.handleJobComplete(jobId, change.new.output as Output);\n } else if (newStatus === JobStatus.FAILED) {\n this.handleJobError(\n jobId,\n change.new.error ?? \"Job failed\",\n change.new.error_code ?? undefined\n );\n } else if (newStatus === JobStatus.DISABLED) {\n this.handleJobDisabled(jobId);\n } else if (newStatus === JobStatus.PENDING && oldStatus === JobStatus.PROCESSING) {\n // Retry\n const runAfter = change.new.run_after ? new Date(change.new.run_after) : new Date();\n this.handleJobRetry(jobId, runAfter);\n }\n\n // Progress update\n if (\n change.new.progress !== change.old?.progress ||\n change.new.progress_message !== change.old?.progress_message\n ) {\n this.handleJobProgress(\n jobId,\n change.new.progress ?? 0,\n change.new.progress_message ?? \"\",\n change.new.progress_details ?? null\n );\n }\n }\n }\n\n protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output> {\n const toDate = (date: string | null | undefined): Date | null => {\n if (!date) return null;\n const d = new Date(date);\n return isNaN(d.getTime()) ? null : d;\n };\n return new Job<Input, Output>({\n id: details.id,\n jobRunId: details.job_run_id,\n queueName: details.queue,\n fingerprint: details.fingerprint,\n input: details.input as Input,\n output: details.output as Output,\n runAfter: toDate(details.run_after),\n createdAt: toDate(details.created_at)!,\n deadlineAt: toDate(details.deadline_at),\n lastRanAt: toDate(details.last_ran_at),\n completedAt: toDate(details.completed_at),\n progress: details.progress || 0,\n progressMessage: details.progress_message || \"\",\n progressDetails: details.progress_details ?? null,\n status: details.status as JobStatus,\n error: details.error ?? null,\n errorCode: details.error_code ?? null,\n runAttempts: details.run_attempts ?? 0,\n maxRetries: details.max_retries ?? 10,\n });\n }\n\n protected buildErrorFromJob(job: Job<Input, Output>): JobError {\n return this.buildErrorFromCode(job.error || \"Job failed\", job.errorCode ?? undefined);\n }\n\n protected buildErrorFromCode(message: string, errorCode?: string): JobError {\n if (errorCode === \"PermanentJobError\") {\n return new PermanentJobError(message);\n }\n if (errorCode === \"RetryableJobError\") {\n return new RetryableJobError(message);\n }\n if (errorCode === \"AbortSignalJobError\") {\n return new AbortSignalJobError(message);\n }\n if (errorCode === \"JobDisabledError\") {\n return new JobDisabledError(message);\n }\n return new JobError(message);\n }\n}\n",
|
|
8
8
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IQueueStorage, JobStatus, JobStorageFormat } from \"@workglow/storage\";\nimport { EventEmitter } from \"@workglow/util\";\nimport { ILimiter } from \"../limiter/ILimiter\";\nimport { NullLimiter } from \"../limiter/NullLimiter\";\nimport { Job, JobClass } from \"./Job\";\nimport { JobQueueClient } from \"./JobQueueClient\";\nimport { JobQueueWorker } from \"./JobQueueWorker\";\n\n/**\n * Statistics tracked for the job queue\n */\nexport interface JobQueueStats {\n readonly totalJobs: number;\n readonly completedJobs: number;\n readonly failedJobs: number;\n readonly abortedJobs: number;\n readonly retriedJobs: number;\n readonly disabledJobs: number;\n readonly averageProcessingTime?: number;\n readonly lastUpdateTime: Date;\n}\n\n/**\n * Events emitted by JobQueueServer\n */\nexport type JobQueueServerEventListeners<Input, Output> = {\n server_start: (queueName: string) => void;\n server_stop: (queueName: string) => void;\n stats_update: (queueName: string, stats: JobQueueStats) => void;\n job_start: (queueName: string, jobId: unknown) => void;\n job_complete: (queueName: string, jobId: unknown, output: Output) => void;\n job_error: (queueName: string, jobId: unknown, error: string) => void;\n job_disabled: (queueName: string, jobId: unknown) => void;\n job_retry: (queueName: string, jobId: unknown, runAfter: Date) => void;\n job_progress: (\n queueName: string,\n jobId: unknown,\n progress: number,\n message: string,\n details: Record<string, unknown> | null\n ) => void;\n};\n\nexport type JobQueueServerEvents = keyof JobQueueServerEventListeners<unknown, unknown>;\n\n/**\n * Options for creating a JobQueueServer\n */\nexport interface JobQueueServerOptions<Input, Output> {\n readonly storage: IQueueStorage<Input, Output>;\n readonly queueName: string;\n readonly limiter?: ILimiter;\n readonly workerCount?: number;\n readonly pollIntervalMs?: number;\n readonly deleteAfterCompletionMs?: number;\n readonly deleteAfterFailureMs?: number;\n readonly deleteAfterDisabledMs?: number;\n readonly cleanupIntervalMs?: number;\n}\n\n/**\n * Server that coordinates multiple workers and manages the job queue lifecycle.\n * Handles stuck job recovery, cleanup, and aggregates statistics.\n */\nexport class JobQueueServer<\n Input,\n Output,\n QueueJob extends Job<Input, Output> = Job<Input, Output>,\n> {\n public readonly queueName: string;\n protected readonly storage: IQueueStorage<Input, Output>;\n protected readonly jobClass: JobClass<Input, Output>;\n protected readonly limiter: ILimiter;\n protected readonly workerCount: number;\n protected readonly pollIntervalMs: number;\n protected readonly deleteAfterCompletionMs?: number;\n protected readonly deleteAfterFailureMs?: number;\n protected readonly deleteAfterDisabledMs?: number;\n protected readonly cleanupIntervalMs: number;\n\n protected readonly events = new EventEmitter<JobQueueServerEventListeners<Input, Output>>();\n protected readonly workers: JobQueueWorker<Input, Output, QueueJob>[] = [];\n protected readonly clients: Set<JobQueueClient<Input, Output>> = new Set();\n\n protected running = false;\n protected cleanupTimer: ReturnType<typeof setTimeout> | null = null;\n\n protected stats: JobQueueStats = {\n totalJobs: 0,\n completedJobs: 0,\n failedJobs: 0,\n abortedJobs: 0,\n retriedJobs: 0,\n disabledJobs: 0,\n lastUpdateTime: new Date(),\n };\n\n constructor(jobClass: JobClass<Input, Output>, options: JobQueueServerOptions<Input, Output>) {\n this.queueName = options.queueName;\n this.storage = options.storage;\n this.jobClass = jobClass;\n this.limiter = options.limiter ?? new NullLimiter();\n this.workerCount = options.workerCount ?? 1;\n this.pollIntervalMs = options.pollIntervalMs ?? 100;\n this.deleteAfterCompletionMs = options.deleteAfterCompletionMs;\n this.deleteAfterFailureMs = options.deleteAfterFailureMs;\n this.deleteAfterDisabledMs = options.deleteAfterDisabledMs;\n this.cleanupIntervalMs = options.cleanupIntervalMs ?? 10000;\n\n this.initializeWorkers();\n }\n\n /**\n * Start the server and all workers\n */\n public async start(): Promise<this> {\n if (this.running) {\n return this;\n }\n\n this.running = true;\n this.events.emit(\"server_start\", this.queueName);\n\n // Fix stuck jobs from previous runs\n await this.fixupJobs();\n\n // Start all workers\n await Promise.all(this.workers.map((worker) => worker.start()));\n\n // Start cleanup loop\n this.startCleanupLoop();\n\n return this;\n }\n\n /**\n * Stop the server and all workers\n */\n public async stop(): Promise<this> {\n if (!this.running) {\n return this;\n }\n\n this.running = false;\n\n // Stop cleanup loop\n if (this.cleanupTimer) {\n clearTimeout(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n\n // Stop all workers\n await Promise.all(this.workers.map((worker) => worker.stop()));\n\n this.events.emit(\"server_stop\", this.queueName);\n return this;\n }\n\n /**\n * Get the current queue statistics\n */\n public getStats(): JobQueueStats {\n return { ...this.stats };\n }\n\n /**\n * Get the storage instance (for client connection)\n */\n public getStorage(): IQueueStorage<Input, Output> {\n return this.storage;\n }\n\n /**\n * Scale the number of workers\n */\n public async scaleWorkers(count: number): Promise<void> {\n if (count < 1) {\n throw new Error(\"Worker count must be at least 1\");\n }\n\n const currentCount = this.workers.length;\n\n if (count > currentCount) {\n // Add more workers\n for (let i = currentCount; i < count; i++) {\n const worker = this.createWorker();\n this.workers.push(worker);\n if (this.running) {\n await worker.start();\n }\n }\n } else if (count < currentCount) {\n // Remove workers\n const toRemove = this.workers.splice(count);\n await Promise.all(toRemove.map((worker) => worker.stop()));\n }\n }\n\n /**\n * Check if the server is running\n */\n public isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the number of workers\n */\n public getWorkerCount(): number {\n return this.workers.length;\n }\n\n // ========================================================================\n // Client management\n // ========================================================================\n\n /**\n * Add a client for same-process event forwarding\n * @internal\n */\n public addClient(client: JobQueueClient<Input, Output>): void {\n this.clients.add(client);\n }\n\n /**\n * Remove a client\n * @internal\n */\n public removeClient(client: JobQueueClient<Input, Output>): void {\n this.clients.delete(client);\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n public on<Event extends JobQueueServerEvents>(\n event: Event,\n listener: JobQueueServerEventListeners<Input, Output>[Event]\n ): void {\n this.events.on(event, listener);\n }\n\n public off<Event extends JobQueueServerEvents>(\n event: Event,\n listener: JobQueueServerEventListeners<Input, Output>[Event]\n ): void {\n this.events.off(event, listener);\n }\n\n // ========================================================================\n // Protected methods\n // ========================================================================\n\n /**\n * Initialize workers\n */\n protected initializeWorkers(): void {\n for (let i = 0; i < this.workerCount; i++) {\n const worker = this.createWorker();\n this.workers.push(worker);\n }\n }\n\n /**\n * Create a new worker and wire up event forwarding\n */\n protected createWorker(): JobQueueWorker<Input, Output, QueueJob> {\n const worker = new JobQueueWorker<Input, Output, QueueJob>(this.jobClass, {\n storage: this.storage,\n queueName: this.queueName,\n limiter: this.limiter,\n pollIntervalMs: this.pollIntervalMs,\n });\n\n // Forward worker events to server and clients\n worker.on(\"job_start\", (jobId) => {\n this.stats = { ...this.stats, totalJobs: this.stats.totalJobs + 1 };\n this.events.emit(\"job_start\", this.queueName, jobId);\n this.forwardToClients(\"handleJobStart\", jobId);\n });\n\n worker.on(\"job_complete\", async (jobId, output) => {\n this.stats = { ...this.stats, completedJobs: this.stats.completedJobs + 1 };\n this.updateAverageProcessingTime();\n this.events.emit(\"job_complete\", this.queueName, jobId, output);\n this.forwardToClients(\"handleJobComplete\", jobId, output);\n\n // Immediate deletion when configured\n if (this.deleteAfterCompletionMs === 0) {\n await this.storage.delete(jobId);\n }\n });\n\n worker.on(\"job_error\", async (jobId, error, errorCode) => {\n this.stats = { ...this.stats, failedJobs: this.stats.failedJobs + 1 };\n this.events.emit(\"job_error\", this.queueName, jobId, error);\n this.forwardToClients(\"handleJobError\", jobId, error, errorCode);\n\n // Immediate deletion when configured\n if (this.deleteAfterFailureMs === 0) {\n await this.storage.delete(jobId);\n }\n });\n\n worker.on(\"job_disabled\", async (jobId) => {\n this.stats = { ...this.stats, disabledJobs: this.stats.disabledJobs + 1 };\n this.events.emit(\"job_disabled\", this.queueName, jobId);\n this.forwardToClients(\"handleJobDisabled\", jobId);\n\n // Immediate deletion when configured\n if (this.deleteAfterDisabledMs === 0) {\n await this.storage.delete(jobId);\n }\n });\n\n worker.on(\"job_retry\", (jobId, runAfter) => {\n this.stats = { ...this.stats, retriedJobs: this.stats.retriedJobs + 1 };\n this.events.emit(\"job_retry\", this.queueName, jobId, runAfter);\n this.forwardToClients(\"handleJobRetry\", jobId, runAfter);\n });\n\n worker.on(\"job_progress\", (jobId, progress, message, details) => {\n this.events.emit(\"job_progress\", this.queueName, jobId, progress, message, details);\n this.forwardToClients(\"handleJobProgress\", jobId, progress, message, details);\n });\n\n return worker;\n }\n\n /**\n * Forward events to all attached clients\n */\n protected forwardToClients(method: \"handleJobStart\", jobId: unknown): void;\n protected forwardToClients(method: \"handleJobComplete\", jobId: unknown, output: Output): void;\n protected forwardToClients(\n method: \"handleJobError\",\n jobId: unknown,\n error: string,\n errorCode?: string\n ): void;\n protected forwardToClients(method: \"handleJobDisabled\", jobId: unknown): void;\n protected forwardToClients(method: \"handleJobRetry\", jobId: unknown, runAfter: Date): void;\n protected forwardToClients(\n method: \"handleJobProgress\",\n jobId: unknown,\n progress: number,\n message: string,\n details: Record<string, unknown> | null\n ): void;\n protected forwardToClients(method: string, ...args: unknown[]): void {\n for (const client of this.clients) {\n const fn = (client as any)[method];\n if (typeof fn === \"function\") {\n fn.apply(client, args);\n }\n }\n }\n\n /**\n * Update average processing time from all workers\n */\n protected updateAverageProcessingTime(): void {\n const times: number[] = [];\n for (const worker of this.workers) {\n const avgTime = worker.getAverageProcessingTime();\n if (avgTime !== undefined) {\n times.push(avgTime);\n }\n }\n if (times.length > 0) {\n const avg = times.reduce((a, b) => a + b, 0) / times.length;\n this.stats = {\n ...this.stats,\n averageProcessingTime: avg,\n lastUpdateTime: new Date(),\n };\n }\n }\n\n /**\n * Start the cleanup loop\n */\n protected startCleanupLoop(): void {\n if (!this.running) return;\n\n this.cleanupJobs().finally(() => {\n if (this.running) {\n this.cleanupTimer = setTimeout(() => this.startCleanupLoop(), this.cleanupIntervalMs);\n }\n });\n }\n\n /**\n * Clean up completed/failed jobs based on TTL settings\n */\n protected async cleanupJobs(): Promise<void> {\n try {\n // The workers will handle the abort via their abort controllers\n // We just need to ensure the jobs get marked as failed\n\n // Delete completed jobs after TTL\n if (this.deleteAfterCompletionMs !== undefined && this.deleteAfterCompletionMs > 0) {\n await this.storage.deleteJobsByStatusAndAge(\n JobStatus.COMPLETED,\n this.deleteAfterCompletionMs\n );\n }\n\n // Delete failed jobs after TTL\n if (this.deleteAfterFailureMs !== undefined && this.deleteAfterFailureMs > 0) {\n await this.storage.deleteJobsByStatusAndAge(JobStatus.FAILED, this.deleteAfterFailureMs);\n }\n\n // Delete disabled jobs after TTL\n if (this.deleteAfterDisabledMs !== undefined && this.deleteAfterDisabledMs > 0) {\n await this.storage.deleteJobsByStatusAndAge(JobStatus.DISABLED, this.deleteAfterDisabledMs);\n }\n } catch (error) {\n console.error(\"Error in cleanup:\", error);\n }\n }\n\n /**\n * Fix stuck jobs from previous server runs\n */\n protected async fixupJobs(): Promise<void> {\n try {\n const stuckProcessingJobs = await this.storage.peek(JobStatus.PROCESSING);\n const stuckAbortingJobs = await this.storage.peek(JobStatus.ABORTING);\n const stuckJobs = [...stuckProcessingJobs, ...stuckAbortingJobs];\n\n for (const jobData of stuckJobs) {\n const job = this.storageToClass(jobData);\n if (job.runAttempts >= job.maxRetries) {\n job.status = JobStatus.FAILED;\n job.error = \"Max retries reached\";\n job.errorCode = \"MAX_RETRIES_REACHED\";\n } else {\n job.status = JobStatus.PENDING;\n job.runAfter = job.lastRanAt || new Date();\n job.progress = 0;\n job.progressMessage = \"\";\n job.progressDetails = null;\n job.error = \"Server restarted\";\n }\n\n await this.storage.complete(this.classToStorage(job));\n }\n } catch (error) {\n console.error(\"Error in fixupJobs:\", error);\n }\n }\n\n /**\n * Convert storage format to Job class\n */\n protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output> {\n const toDate = (date: string | null | undefined): Date | null => {\n if (!date) return null;\n const d = new Date(date);\n return isNaN(d.getTime()) ? null : d;\n };\n return new this.jobClass({\n id: details.id,\n jobRunId: details.job_run_id,\n queueName: details.queue,\n fingerprint: details.fingerprint,\n input: details.input as Input,\n output: details.output as Output,\n runAfter: toDate(details.run_after),\n createdAt: toDate(details.created_at)!,\n deadlineAt: toDate(details.deadline_at),\n lastRanAt: toDate(details.last_ran_at),\n completedAt: toDate(details.completed_at),\n progress: details.progress || 0,\n progressMessage: details.progress_message || \"\",\n progressDetails: details.progress_details ?? null,\n status: details.status as JobStatus,\n error: details.error ?? null,\n errorCode: details.error_code ?? null,\n runAttempts: details.run_attempts ?? 0,\n maxRetries: details.max_retries ?? 10,\n });\n }\n\n /**\n * Convert Job class to storage format\n */\n protected classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output> {\n const dateToISOString = (date: Date | null | undefined): string | null => {\n if (!date) return null;\n return isNaN(date.getTime()) ? null : date.toISOString();\n };\n const now = new Date().toISOString();\n return {\n id: job.id,\n job_run_id: job.jobRunId,\n queue: job.queueName || this.queueName,\n fingerprint: job.fingerprint,\n input: job.input,\n status: job.status,\n output: job.output ?? null,\n error: job.error === null ? null : String(job.error),\n error_code: job.errorCode || null,\n run_attempts: job.runAttempts ?? 0,\n max_retries: job.maxRetries ?? 10,\n run_after: dateToISOString(job.runAfter) ?? now,\n created_at: dateToISOString(job.createdAt) ?? now,\n deadline_at: dateToISOString(job.deadlineAt),\n last_ran_at: dateToISOString(job.lastRanAt),\n completed_at: dateToISOString(job.completedAt),\n progress: job.progress ?? 0,\n progress_message: job.progressMessage ?? \"\",\n progress_details: job.progressDetails ?? null,\n };\n }\n}\n",
|
|
9
9
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createServiceToken } from \"@workglow/util\";\nimport { ILimiter } from \"./ILimiter\";\n\nexport const NULL_JOB_LIMITER = createServiceToken<ILimiter>(\"jobqueue.limiter.null\");\n\n/**\n * Null limiter that does nothing.\n */\nexport class NullLimiter implements ILimiter {\n async canProceed(): Promise<boolean> {\n return true;\n }\n\n async recordJobStart(): Promise<void> {\n // Do nothing\n }\n\n async recordJobCompletion(): Promise<void> {\n // Do nothing\n }\n\n async getNextAvailableTime(): Promise<Date> {\n return new Date();\n }\n\n async setNextAvailableTime(date: Date): Promise<void> {\n // Do nothing\n }\n\n async clear(): Promise<void> {\n // Do nothing\n }\n}\n",
|
|
10
|
-
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IQueueStorage, JobStatus, JobStorageFormat } from \"@workglow/storage\";\nimport { EventEmitter, sleep, uuid4 } from \"@workglow/util\";\nimport { ILimiter } from \"../limiter/ILimiter\";\nimport { NullLimiter } from \"../limiter/NullLimiter\";\nimport { Job, JobClass } from \"./Job\";\nimport {\n AbortSignalJobError,\n JobDisabledError,\n JobError,\n JobNotFoundError,\n PermanentJobError,\n RetryableJobError,\n} from \"./JobError\";\n\n/**\n * Events emitted by JobQueueWorker\n */\nexport type JobQueueWorkerEventListeners<Input, Output> = {\n job_start: (jobId: unknown) => void;\n job_complete: (jobId: unknown, output: Output) => void;\n job_error: (jobId: unknown, error: string, errorCode?: string) => void;\n job_disabled: (jobId: unknown) => void;\n job_retry: (jobId: unknown, runAfter: Date) => void;\n job_progress: (\n jobId: unknown,\n progress: number,\n message: string,\n details: Record<string, unknown> | null\n ) => void;\n worker_start: () => void;\n worker_stop: () => void;\n};\n\nexport type JobQueueWorkerEvents = keyof JobQueueWorkerEventListeners<unknown, unknown>;\n\n/**\n * Options for creating a JobQueueWorker\n */\nexport interface JobQueueWorkerOptions<Input, Output> {\n readonly storage: IQueueStorage<Input, Output>;\n readonly queueName: string;\n readonly limiter?: ILimiter;\n readonly pollIntervalMs?: number;\n}\n\n/**\n * Worker that processes jobs from the queue.\n * Reports progress and completion back to storage.\n */\nexport class JobQueueWorker<\n Input,\n Output,\n QueueJob extends Job<Input, Output> = Job<Input, Output>,\n> {\n public readonly queueName: string;\n public readonly workerId: string;\n protected readonly storage: IQueueStorage<Input, Output>;\n protected readonly jobClass: JobClass<Input, Output>;\n protected readonly limiter: ILimiter;\n protected readonly pollIntervalMs: number;\n protected readonly events = new EventEmitter<JobQueueWorkerEventListeners<Input, Output>>();\n\n protected running = false;\n\n /**\n * Abort controllers for active jobs\n */\n protected readonly activeJobAbortControllers: Map<unknown, AbortController> = new Map();\n\n /**\n * Processing times for statistics\n */\n protected readonly processingTimes: Map<unknown, number> = new Map();\n\n constructor(jobClass: JobClass<Input, Output>, options: JobQueueWorkerOptions<Input, Output>) {\n this.queueName = options.queueName;\n this.workerId = uuid4();\n this.storage = options.storage;\n this.jobClass = jobClass;\n this.limiter = options.limiter ?? new NullLimiter();\n this.pollIntervalMs = options.pollIntervalMs ?? 100;\n }\n\n /**\n * Start the worker processing loop\n */\n public async start(): Promise<this> {\n if (this.running) {\n return this;\n }\n this.running = true;\n this.events.emit(\"worker_start\");\n this.processJobs();\n return this;\n }\n\n /**\n * Stop the worker and abort any active jobs\n */\n public async stop(): Promise<this> {\n if (!this.running) {\n return this;\n }\n this.running = false;\n\n // Wait for pending operations to settle\n const size = await this.storage.size(JobStatus.PROCESSING);\n const sleepTime = Math.max(100, size * 2);\n await sleep(sleepTime);\n\n // Abort all active jobs\n for (const controller of this.activeJobAbortControllers.values()) {\n if (!controller.signal.aborted) {\n controller.abort();\n }\n }\n\n await sleep(sleepTime);\n this.events.emit(\"worker_stop\");\n return this;\n }\n\n /**\n * Process a single job manually (useful for testing or manual control)\n */\n public async processNext(): Promise<boolean> {\n const canProceed = await this.limiter.canProceed();\n if (!canProceed) {\n return false;\n }\n\n const job = await this.next();\n if (!job) {\n return false;\n }\n\n await this.processSingleJob(job);\n return true;\n }\n\n /**\n * Check if the worker is currently running\n */\n public isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the number of active jobs being processed\n */\n public getActiveJobCount(): number {\n return this.activeJobAbortControllers.size;\n }\n\n /**\n * Get average processing time\n */\n public getAverageProcessingTime(): number | undefined {\n const times = Array.from(this.processingTimes.values());\n if (times.length === 0) return undefined;\n return times.reduce((a, b) => a + b, 0) / times.length;\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n public on<Event extends JobQueueWorkerEvents>(\n event: Event,\n listener: JobQueueWorkerEventListeners<Input, Output>[Event]\n ): void {\n this.events.on(event, listener);\n }\n\n public off<Event extends JobQueueWorkerEvents>(\n event: Event,\n listener: JobQueueWorkerEventListeners<Input, Output>[Event]\n ): void {\n this.events.off(event, listener);\n }\n\n // ========================================================================\n // Protected methods\n // ========================================================================\n\n /**\n * Get the next job from the queue\n */\n protected async next(): Promise<QueueJob | undefined> {\n const job = await this.storage.next(this.workerId);\n if (!job) return undefined;\n return this.storageToClass(job) as QueueJob;\n }\n\n /**\n * Main job processing loop\n */\n protected async processJobs(): Promise<void> {\n if (!this.running) {\n return;\n }\n\n try {\n // Check for aborting jobs\n await this.checkForAbortingJobs();\n\n const canProceed = await this.limiter.canProceed();\n if (canProceed) {\n const job = await this.next();\n if (job) {\n // Don't await - process in background to allow concurrent jobs\n this.processSingleJob(job);\n } else {\n await sleep(this.pollIntervalMs);\n }\n }\n } finally {\n if (this.running) {\n setTimeout(() => this.processJobs(), this.pollIntervalMs);\n }\n }\n }\n\n /**\n * Check for jobs that have been marked for abort and trigger their abort controllers\n */\n protected async checkForAbortingJobs(): Promise<void> {\n const abortingJobs = await this.storage.peek(JobStatus.ABORTING);\n for (const jobData of abortingJobs) {\n const controller = this.activeJobAbortControllers.get(jobData.id);\n if (controller && !controller.signal.aborted) {\n controller.abort();\n }\n }\n }\n\n /**\n * Process a single job\n */\n protected async processSingleJob(job: Job<Input, Output>): Promise<void> {\n if (!job || !job.id) {\n throw new JobNotFoundError(\"Invalid job provided for processing\");\n }\n\n const startTime = Date.now();\n\n try {\n await this.validateJobState(job);\n await this.limiter.recordJobStart();\n\n const abortController = this.createAbortController(job.id);\n this.events.emit(\"job_start\", job.id);\n\n const output = await this.executeJob(job, abortController.signal);\n await this.completeJob(job, output);\n\n this.processingTimes.set(job.id, Date.now() - startTime);\n } catch (err: unknown) {\n const error = this.normalizeError(err);\n if (error instanceof RetryableJobError) {\n if (job.runAttempts >= job.maxRetries) {\n await this.failJob(job, new PermanentJobError(\"Max retries reached\"));\n } else {\n await this.rescheduleJob(job, error.retryDate);\n }\n } else {\n await this.failJob(job, error);\n }\n } finally {\n await this.limiter.recordJobCompletion();\n }\n }\n\n /**\n * Execute a job with the provided abort signal\n */\n protected async executeJob(job: Job<Input, Output>, signal: AbortSignal): Promise<Output> {\n if (!job) throw new JobNotFoundError(\"Cannot execute null or undefined job\");\n return await job.execute(job.input, {\n signal,\n updateProgress: this.updateProgress.bind(this, job.id),\n });\n }\n\n /**\n * Update progress for a job\n */\n protected async updateProgress(\n jobId: unknown,\n progress: number,\n message: string = \"\",\n details: Record<string, unknown> | null = null\n ): Promise<void> {\n // Validate progress value\n progress = Math.max(0, Math.min(100, progress));\n\n await this.storage.saveProgress(jobId, progress, message, details);\n this.events.emit(\"job_progress\", jobId, progress, message, details);\n }\n\n /**\n * Mark a job as completed\n */\n protected async completeJob(job: Job<Input, Output>, output?: Output): Promise<void> {\n try {\n job.status = JobStatus.COMPLETED;\n job.progress = 100;\n job.progressMessage = \"\";\n job.progressDetails = null;\n job.completedAt = new Date();\n job.output = output ?? null;\n job.error = null;\n job.errorCode = null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_complete\", job.id, output as Output);\n } catch (err) {\n console.error(\"completeJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Mark a job as failed\n */\n protected async failJob(job: Job<Input, Output>, error: JobError): Promise<void> {\n try {\n job.status = JobStatus.FAILED;\n job.progress = 100;\n job.completedAt = new Date();\n job.progressMessage = \"\";\n job.progressDetails = null;\n job.error = error.message;\n job.errorCode = error?.constructor?.name ?? null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_error\", job.id, error.message, error.constructor.name);\n } catch (err) {\n console.error(\"failJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Mark a job as disabled\n */\n protected async disableJob(job: Job<Input, Output>): Promise<void> {\n try {\n job.status = JobStatus.DISABLED;\n job.progress = 100;\n job.completedAt = new Date();\n job.progressMessage = \"\";\n job.progressDetails = null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_disabled\", job.id);\n } catch (err) {\n console.error(\"disableJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Reschedule a job for retry\n */\n protected async rescheduleJob(job: Job<Input, Output>, retryDate?: Date): Promise<void> {\n try {\n job.status = JobStatus.PENDING;\n const nextAvailableTime = await this.limiter.getNextAvailableTime();\n job.runAfter = retryDate instanceof Date ? retryDate : nextAvailableTime;\n job.progress = 0;\n job.progressMessage = \"\";\n job.progressDetails = null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_retry\", job.id, job.runAfter);\n } catch (err) {\n console.error(\"rescheduleJob errored:\", err);\n }\n }\n\n /**\n * Create an abort controller for a job\n */\n protected createAbortController(jobId: unknown): AbortController {\n if (!jobId) throw new JobNotFoundError(\"Cannot create abort controller for undefined job\");\n\n if (this.activeJobAbortControllers.has(jobId)) {\n return this.activeJobAbortControllers.get(jobId)!;\n }\n\n const abortController = new AbortController();\n abortController.signal.addEventListener(\"abort\", () => this.handleAbort(jobId));\n this.activeJobAbortControllers.set(jobId, abortController);\n return abortController;\n }\n\n /**\n * Handle job abort\n */\n protected async handleAbort(jobId: unknown): Promise<void> {\n const job = await this.getJob(jobId);\n if (!job) {\n console.error(\"handleAbort: job not found\", jobId);\n return;\n }\n const error = new AbortSignalJobError(\"Job Aborted\");\n await this.failJob(job, error);\n }\n\n /**\n * Get a job by ID\n */\n protected async getJob(id: unknown): Promise<Job<Input, Output> | undefined> {\n const job = await this.storage.get(id);\n if (!job) return undefined;\n return this.storageToClass(job);\n }\n\n /**\n * Validate job state before processing\n */\n protected async validateJobState(job: Job<Input, Output>): Promise<void> {\n if (job.status === JobStatus.COMPLETED) {\n throw new PermanentJobError(`Job ${job.id} is already completed`);\n }\n if (job.status === JobStatus.FAILED) {\n throw new PermanentJobError(`Job ${job.id} has failed`);\n }\n if (\n job.status === JobStatus.ABORTING ||\n this.activeJobAbortControllers.get(job.id)?.signal.aborted\n ) {\n throw new AbortSignalJobError(`Job ${job.id} is being aborted`);\n }\n if (job.deadlineAt && job.deadlineAt < new Date()) {\n throw new PermanentJobError(`Job ${job.id} has exceeded its deadline`);\n }\n if (job.status === JobStatus.DISABLED) {\n throw new JobDisabledError(`Job ${job.id} has been disabled`);\n }\n }\n\n /**\n * Normalize errors into JobError instances\n */\n protected normalizeError(err: unknown): JobError {\n if (err instanceof JobError) {\n return err;\n }\n if (err instanceof Error) {\n return new PermanentJobError(err.message);\n }\n return new PermanentJobError(String(err));\n }\n\n /**\n * Clean up job state after completion/failure\n */\n protected cleanupJob(jobId: unknown): void {\n this.activeJobAbortControllers.delete(jobId);\n }\n\n /**\n * Convert storage format to Job class\n */\n protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output> {\n const toDate = (date: string | null | undefined): Date | null => {\n if (!date) return null;\n const d = new Date(date);\n return isNaN(d.getTime()) ? null : d;\n };\n return new this.jobClass({\n id: details.id,\n jobRunId: details.job_run_id,\n queueName: details.queue,\n fingerprint: details.fingerprint,\n input: details.input as Input,\n output: details.output as Output,\n runAfter: toDate(details.run_after),\n createdAt: toDate(details.created_at)!,\n deadlineAt: toDate(details.deadline_at),\n lastRanAt: toDate(details.last_ran_at),\n completedAt: toDate(details.completed_at),\n progress: details.progress || 0,\n progressMessage: details.progress_message || \"\",\n progressDetails: details.progress_details ?? null,\n status: details.status as JobStatus,\n error: details.error ?? null,\n errorCode: details.error_code ?? null,\n runAttempts: details.run_attempts ?? 0,\n maxRetries: details.max_retries ?? 10,\n });\n }\n\n /**\n * Convert Job class to storage format\n */\n protected classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output> {\n const dateToISOString = (date: Date | null | undefined): string | null => {\n if (!date) return null;\n return isNaN(date.getTime()) ? null : date.toISOString();\n };\n const now = new Date().toISOString();\n return {\n id: job.id,\n job_run_id: job.jobRunId,\n queue: job.queueName || this.queueName,\n fingerprint: job.fingerprint,\n input: job.input,\n status: job.status,\n output: job.output ?? null,\n error: job.error === null ? null : String(job.error),\n error_code: job.errorCode || null,\n run_attempts: job.runAttempts ?? 0,\n max_retries: job.maxRetries ?? 10,\n run_after: dateToISOString(job.runAfter) ?? now,\n created_at: dateToISOString(job.createdAt) ?? now,\n deadline_at: dateToISOString(job.deadlineAt),\n last_ran_at: dateToISOString(job.lastRanAt),\n completed_at: dateToISOString(job.completedAt),\n progress: job.progress ?? 0,\n progress_message: job.progressMessage ?? \"\",\n progress_details: job.progressDetails ?? null,\n };\n }\n}\n",
|
|
10
|
+
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IQueueStorage, JobStatus, JobStorageFormat } from \"@workglow/storage\";\nimport { EventEmitter, sleep, uuid4 } from \"@workglow/util\";\nimport { ILimiter } from \"../limiter/ILimiter\";\nimport { NullLimiter } from \"../limiter/NullLimiter\";\nimport { Job, JobClass } from \"./Job\";\nimport {\n AbortSignalJobError,\n JobDisabledError,\n JobError,\n JobNotFoundError,\n PermanentJobError,\n RetryableJobError,\n} from \"./JobError\";\n\n/**\n * Events emitted by JobQueueWorker\n */\nexport type JobQueueWorkerEventListeners<Input, Output> = {\n job_start: (jobId: unknown) => void;\n job_complete: (jobId: unknown, output: Output) => void;\n job_error: (jobId: unknown, error: string, errorCode?: string) => void;\n job_disabled: (jobId: unknown) => void;\n job_retry: (jobId: unknown, runAfter: Date) => void;\n job_progress: (\n jobId: unknown,\n progress: number,\n message: string,\n details: Record<string, unknown> | null\n ) => void;\n worker_start: () => void;\n worker_stop: () => void;\n};\n\nexport type JobQueueWorkerEvents = keyof JobQueueWorkerEventListeners<unknown, unknown>;\n\n/**\n * Options for creating a JobQueueWorker\n */\nexport interface JobQueueWorkerOptions<Input, Output> {\n readonly storage: IQueueStorage<Input, Output>;\n readonly queueName: string;\n readonly limiter?: ILimiter;\n readonly pollIntervalMs?: number;\n}\n\n/**\n * Worker that processes jobs from the queue.\n * Reports progress and completion back to storage.\n */\nexport class JobQueueWorker<\n Input,\n Output,\n QueueJob extends Job<Input, Output> = Job<Input, Output>,\n> {\n public readonly queueName: string;\n public readonly workerId: string;\n protected readonly storage: IQueueStorage<Input, Output>;\n protected readonly jobClass: JobClass<Input, Output>;\n protected readonly limiter: ILimiter;\n protected readonly pollIntervalMs: number;\n protected readonly events = new EventEmitter<JobQueueWorkerEventListeners<Input, Output>>();\n\n protected running = false;\n\n /**\n * Abort controllers for active jobs\n */\n protected readonly activeJobAbortControllers: Map<unknown, AbortController> = new Map();\n\n /**\n * Processing times for statistics\n */\n protected readonly processingTimes: Map<unknown, number> = new Map();\n\n constructor(jobClass: JobClass<Input, Output>, options: JobQueueWorkerOptions<Input, Output>) {\n this.queueName = options.queueName;\n this.workerId = uuid4();\n this.storage = options.storage;\n this.jobClass = jobClass;\n this.limiter = options.limiter ?? new NullLimiter();\n this.pollIntervalMs = options.pollIntervalMs ?? 100;\n }\n\n /**\n * Start the worker processing loop\n */\n public async start(): Promise<this> {\n if (this.running) {\n return this;\n }\n this.running = true;\n this.events.emit(\"worker_start\");\n this.processJobs();\n return this;\n }\n\n /**\n * Stop the worker and abort any active jobs\n */\n public async stop(): Promise<this> {\n if (!this.running) {\n return this;\n }\n this.running = false;\n\n // Wait for pending operations to settle\n const size = await this.storage.size(JobStatus.PROCESSING);\n const sleepTime = Math.max(100, size * 2);\n await sleep(sleepTime);\n\n // Abort all active jobs\n for (const controller of this.activeJobAbortControllers.values()) {\n if (!controller.signal.aborted) {\n controller.abort();\n }\n }\n\n await sleep(sleepTime);\n this.events.emit(\"worker_stop\");\n return this;\n }\n\n /**\n * Process a single job manually (useful for testing or manual control)\n */\n public async processNext(): Promise<boolean> {\n const canProceed = await this.limiter.canProceed();\n if (!canProceed) {\n return false;\n }\n\n const job = await this.next();\n if (!job) {\n return false;\n }\n\n await this.processSingleJob(job);\n return true;\n }\n\n /**\n * Check if the worker is currently running\n */\n public isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the number of active jobs being processed\n */\n public getActiveJobCount(): number {\n return this.activeJobAbortControllers.size;\n }\n\n /**\n * Get average processing time\n */\n public getAverageProcessingTime(): number | undefined {\n const times = Array.from(this.processingTimes.values());\n if (times.length === 0) return undefined;\n return times.reduce((a, b) => a + b, 0) / times.length;\n }\n\n // ========================================================================\n // Event handling\n // ========================================================================\n\n public on<Event extends JobQueueWorkerEvents>(\n event: Event,\n listener: JobQueueWorkerEventListeners<Input, Output>[Event]\n ): void {\n this.events.on(event, listener);\n }\n\n public off<Event extends JobQueueWorkerEvents>(\n event: Event,\n listener: JobQueueWorkerEventListeners<Input, Output>[Event]\n ): void {\n this.events.off(event, listener);\n }\n\n // ========================================================================\n // Protected methods\n // ========================================================================\n\n /**\n * Get the next job from the queue\n */\n protected async next(): Promise<QueueJob | undefined> {\n const job = await this.storage.next(this.workerId);\n if (!job) return undefined;\n return this.storageToClass(job) as QueueJob;\n }\n\n /**\n * Main job processing loop\n */\n protected async processJobs(): Promise<void> {\n if (!this.running) {\n return;\n }\n\n try {\n // Check for aborting jobs\n await this.checkForAbortingJobs();\n\n const canProceed = await this.limiter.canProceed();\n if (canProceed) {\n const job = await this.next();\n if (job) {\n // Don't await - process in background to allow concurrent jobs\n this.processSingleJob(job);\n } else {\n await sleep(this.pollIntervalMs);\n }\n }\n } finally {\n if (this.running) {\n setTimeout(() => this.processJobs(), this.pollIntervalMs);\n }\n }\n }\n\n /**\n * Check for jobs that have been marked for abort and trigger their abort controllers\n */\n protected async checkForAbortingJobs(): Promise<void> {\n const abortingJobs = await this.storage.peek(JobStatus.ABORTING);\n for (const jobData of abortingJobs) {\n const controller = this.activeJobAbortControllers.get(jobData.id);\n if (controller && !controller.signal.aborted) {\n controller.abort();\n }\n }\n }\n\n /**\n * Process a single job\n */\n protected async processSingleJob(job: Job<Input, Output>): Promise<void> {\n if (!job || !job.id) {\n throw new JobNotFoundError(\"Invalid job provided for processing\");\n }\n\n const startTime = Date.now();\n\n try {\n await this.validateJobState(job);\n await this.limiter.recordJobStart();\n\n const abortController = this.createAbortController(job.id);\n this.events.emit(\"job_start\", job.id);\n\n const output = await this.executeJob(job, abortController.signal);\n await this.completeJob(job, output);\n\n this.processingTimes.set(job.id, Date.now() - startTime);\n } catch (err: unknown) {\n const error = this.normalizeError(err);\n if (error instanceof RetryableJobError) {\n const currentJob = await this.getJob(job.id);\n if (!currentJob) {\n throw new JobNotFoundError(`Job ${job.id} not found`);\n }\n\n if (currentJob.runAttempts >= currentJob.maxRetries) {\n await this.failJob(currentJob, new PermanentJobError(\"Max retries reached\"));\n } else {\n await this.rescheduleJob(currentJob, error.retryDate);\n }\n } else {\n await this.failJob(job, error);\n }\n } finally {\n await this.limiter.recordJobCompletion();\n }\n }\n\n /**\n * Execute a job with the provided abort signal\n */\n protected async executeJob(job: Job<Input, Output>, signal: AbortSignal): Promise<Output> {\n if (!job) throw new JobNotFoundError(\"Cannot execute null or undefined job\");\n return await job.execute(job.input, {\n signal,\n updateProgress: this.updateProgress.bind(this, job.id),\n });\n }\n\n /**\n * Update progress for a job\n */\n protected async updateProgress(\n jobId: unknown,\n progress: number,\n message: string = \"\",\n details: Record<string, unknown> | null = null\n ): Promise<void> {\n // Validate progress value\n progress = Math.max(0, Math.min(100, progress));\n\n await this.storage.saveProgress(jobId, progress, message, details);\n this.events.emit(\"job_progress\", jobId, progress, message, details);\n }\n\n /**\n * Mark a job as completed\n */\n protected async completeJob(job: Job<Input, Output>, output?: Output): Promise<void> {\n try {\n job.status = JobStatus.COMPLETED;\n job.progress = 100;\n job.progressMessage = \"\";\n job.progressDetails = null;\n job.completedAt = new Date();\n job.output = output ?? null;\n job.error = null;\n job.errorCode = null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_complete\", job.id, output as Output);\n } catch (err) {\n console.error(\"completeJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Mark a job as failed\n */\n protected async failJob(job: Job<Input, Output>, error: JobError): Promise<void> {\n try {\n job.status = JobStatus.FAILED;\n job.progress = 100;\n job.completedAt = new Date();\n job.progressMessage = \"\";\n job.progressDetails = null;\n job.error = error.message;\n job.errorCode = error?.constructor?.name ?? null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_error\", job.id, error.message, error.constructor.name);\n } catch (err) {\n console.error(\"failJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Mark a job as disabled\n */\n protected async disableJob(job: Job<Input, Output>): Promise<void> {\n try {\n job.status = JobStatus.DISABLED;\n job.progress = 100;\n job.completedAt = new Date();\n job.progressMessage = \"\";\n job.progressDetails = null;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_disabled\", job.id);\n } catch (err) {\n console.error(\"disableJob errored:\", err);\n } finally {\n this.cleanupJob(job.id);\n }\n }\n\n /**\n * Reschedule a job for retry\n */\n protected async rescheduleJob(job: Job<Input, Output>, retryDate?: Date): Promise<void> {\n try {\n job.status = JobStatus.PENDING;\n const nextAvailableTime = await this.limiter.getNextAvailableTime();\n job.runAfter = retryDate instanceof Date ? retryDate : nextAvailableTime;\n job.progress = 0;\n job.progressMessage = \"\";\n job.progressDetails = null;\n // Increment runAttempts to keep in-memory object in sync with storage\n // The storage layer will read from DB and increment, so this keeps them aligned\n job.runAttempts = (job.runAttempts ?? 0) + 1;\n\n await this.storage.complete(this.classToStorage(job));\n this.events.emit(\"job_retry\", job.id, job.runAfter);\n } catch (err) {\n console.error(\"rescheduleJob errored:\", err);\n }\n }\n\n /**\n * Create an abort controller for a job\n */\n protected createAbortController(jobId: unknown): AbortController {\n if (!jobId) throw new JobNotFoundError(\"Cannot create abort controller for undefined job\");\n\n if (this.activeJobAbortControllers.has(jobId)) {\n return this.activeJobAbortControllers.get(jobId)!;\n }\n\n const abortController = new AbortController();\n abortController.signal.addEventListener(\"abort\", () => this.handleAbort(jobId));\n this.activeJobAbortControllers.set(jobId, abortController);\n return abortController;\n }\n\n /**\n * Handle job abort\n */\n protected async handleAbort(jobId: unknown): Promise<void> {\n const job = await this.getJob(jobId);\n if (!job) {\n console.error(\"handleAbort: job not found\", jobId);\n return;\n }\n const error = new AbortSignalJobError(\"Job Aborted\");\n await this.failJob(job, error);\n }\n\n /**\n * Get a job by ID\n */\n protected async getJob(id: unknown): Promise<Job<Input, Output> | undefined> {\n const job = await this.storage.get(id);\n if (!job) return undefined;\n return this.storageToClass(job);\n }\n\n /**\n * Validate job state before processing\n */\n protected async validateJobState(job: Job<Input, Output>): Promise<void> {\n if (job.status === JobStatus.COMPLETED) {\n throw new PermanentJobError(`Job ${job.id} is already completed`);\n }\n if (job.status === JobStatus.FAILED) {\n throw new PermanentJobError(`Job ${job.id} has failed`);\n }\n if (\n job.status === JobStatus.ABORTING ||\n this.activeJobAbortControllers.get(job.id)?.signal.aborted\n ) {\n throw new AbortSignalJobError(`Job ${job.id} is being aborted`);\n }\n if (job.deadlineAt && job.deadlineAt < new Date()) {\n throw new PermanentJobError(`Job ${job.id} has exceeded its deadline`);\n }\n if (job.status === JobStatus.DISABLED) {\n throw new JobDisabledError(`Job ${job.id} has been disabled`);\n }\n }\n\n /**\n * Normalize errors into JobError instances\n */\n protected normalizeError(err: unknown): JobError {\n if (err instanceof JobError) {\n return err;\n }\n if (err instanceof Error) {\n return new PermanentJobError(err.message);\n }\n return new PermanentJobError(String(err));\n }\n\n /**\n * Clean up job state after completion/failure\n */\n protected cleanupJob(jobId: unknown): void {\n this.activeJobAbortControllers.delete(jobId);\n }\n\n /**\n * Convert storage format to Job class\n */\n protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output> {\n const toDate = (date: string | null | undefined): Date | null => {\n if (!date) return null;\n const d = new Date(date);\n return isNaN(d.getTime()) ? null : d;\n };\n return new this.jobClass({\n id: details.id,\n jobRunId: details.job_run_id,\n queueName: details.queue,\n fingerprint: details.fingerprint,\n input: details.input as Input,\n output: details.output as Output,\n runAfter: toDate(details.run_after),\n createdAt: toDate(details.created_at)!,\n deadlineAt: toDate(details.deadline_at),\n lastRanAt: toDate(details.last_ran_at),\n completedAt: toDate(details.completed_at),\n progress: details.progress || 0,\n progressMessage: details.progress_message || \"\",\n progressDetails: details.progress_details ?? null,\n status: details.status as JobStatus,\n error: details.error ?? null,\n errorCode: details.error_code ?? null,\n runAttempts: details.run_attempts ?? 0,\n maxRetries: details.max_retries ?? 10,\n });\n }\n\n /**\n * Convert Job class to storage format\n */\n protected classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output> {\n const dateToISOString = (date: Date | null | undefined): string | null => {\n if (!date) return null;\n return isNaN(date.getTime()) ? null : date.toISOString();\n };\n const now = new Date().toISOString();\n return {\n id: job.id,\n job_run_id: job.jobRunId,\n queue: job.queueName || this.queueName,\n fingerprint: job.fingerprint,\n input: job.input,\n status: job.status,\n output: job.output ?? null,\n error: job.error === null ? null : String(job.error),\n error_code: job.errorCode || null,\n run_attempts: job.runAttempts ?? 0,\n max_retries: job.maxRetries ?? 10,\n run_after: dateToISOString(job.runAfter) ?? now,\n created_at: dateToISOString(job.createdAt) ?? now,\n deadline_at: dateToISOString(job.deadlineAt),\n last_ran_at: dateToISOString(job.lastRanAt),\n completed_at: dateToISOString(job.completedAt),\n progress: job.progress ?? 0,\n progress_message: job.progressMessage ?? \"\",\n progress_details: job.progressDetails ?? null,\n };\n }\n}\n",
|
|
11
11
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ILimiter } from \"./ILimiter\";\n\nexport class CompositeLimiter implements ILimiter {\n private limiters: ILimiter[] = [];\n\n constructor(limiters: ILimiter[] = []) {\n this.limiters = limiters;\n }\n\n addLimiter(limiter: ILimiter): void {\n this.limiters.push(limiter);\n }\n\n async canProceed(): Promise<boolean> {\n for (const limiter of this.limiters) {\n if (!(await limiter.canProceed())) {\n return false; // If any limiter says \"no\", proceed no further\n }\n }\n return true; // All limiters agree\n }\n\n async recordJobStart(): Promise<void> {\n this.limiters.forEach((limiter) => limiter.recordJobStart());\n }\n\n async recordJobCompletion(): Promise<void> {\n this.limiters.forEach((limiter) => limiter.recordJobCompletion());\n }\n\n async getNextAvailableTime(): Promise<Date> {\n let maxDate = new Date(); // Assume now as the default\n for (const limiter of this.limiters) {\n const limiterNextTime = await limiter.getNextAvailableTime();\n if (limiterNextTime > maxDate) {\n maxDate = limiterNextTime; // Find the latest time among limiters\n }\n }\n return maxDate;\n }\n\n async setNextAvailableTime(date: Date): Promise<void> {\n for (const limiter of this.limiters) {\n await limiter.setNextAvailableTime(date);\n }\n }\n\n async clear(): Promise<void> {\n this.limiters.forEach((limiter) => limiter.clear());\n }\n}\n",
|
|
12
12
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createServiceToken } from \"@workglow/util\";\nimport { ILimiter } from \"./ILimiter\";\n\nexport const CONCURRENT_JOB_LIMITER = createServiceToken<ILimiter>(\"jobqueue.limiter.concurrent\");\n\n/**\n * Concurrency limiter that limits the number of concurrent jobs.\n */\nexport class ConcurrencyLimiter implements ILimiter {\n private currentRunningJobs: number = 0;\n private readonly maxConcurrentJobs: number;\n private readonly timeSliceInMilliseconds: number;\n private nextAllowedStartTime: Date = new Date();\n\n constructor(maxConcurrentJobs: number, timeSliceInMilliseconds: number = 1000) {\n this.maxConcurrentJobs = maxConcurrentJobs;\n this.timeSliceInMilliseconds = timeSliceInMilliseconds;\n }\n\n async canProceed(): Promise<boolean> {\n return (\n this.currentRunningJobs < this.maxConcurrentJobs &&\n Date.now() >= this.nextAllowedStartTime.getTime()\n );\n }\n\n async recordJobStart(): Promise<void> {\n if (this.currentRunningJobs < this.maxConcurrentJobs) {\n this.currentRunningJobs++;\n this.nextAllowedStartTime = new Date(Date.now() + this.timeSliceInMilliseconds);\n }\n }\n\n async recordJobCompletion(): Promise<void> {\n this.currentRunningJobs = Math.max(0, this.currentRunningJobs - 1);\n }\n\n async getNextAvailableTime(): Promise<Date> {\n return this.currentRunningJobs < this.maxConcurrentJobs\n ? new Date()\n : new Date(Date.now() + this.timeSliceInMilliseconds);\n }\n\n async setNextAvailableTime(date: Date): Promise<void> {\n if (date > this.nextAllowedStartTime) {\n this.nextAllowedStartTime = date;\n }\n }\n\n async clear(): Promise<void> {\n this.currentRunningJobs = 0;\n this.nextAllowedStartTime = new Date();\n }\n}\n",
|
|
13
13
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ILimiter } from \"./ILimiter\";\n\nexport class DelayLimiter implements ILimiter {\n private nextAvailableTime: Date = new Date();\n constructor(private delayInMilliseconds: number = 50) {}\n\n async canProceed(): Promise<boolean> {\n return Date.now() >= this.nextAvailableTime.getTime();\n }\n\n async recordJobStart(): Promise<void> {\n this.nextAvailableTime = new Date(Date.now() + this.delayInMilliseconds);\n }\n\n async recordJobCompletion(): Promise<void> {\n // No action needed.\n }\n\n async getNextAvailableTime(): Promise<Date> {\n return this.nextAvailableTime;\n }\n\n async setNextAvailableTime(date: Date): Promise<void> {\n if (date > this.nextAvailableTime) {\n this.nextAvailableTime = date;\n }\n }\n async clear(): Promise<void> {\n this.nextAvailableTime = new Date();\n }\n}\n",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createServiceToken } from \"@workglow/util\";\n\nexport const JOB_LIMITER = createServiceToken<ILimiter>(\"jobqueue.limiter\");\n\n/**\n * Interface for a job limiter.\n */\nexport interface ILimiter {\n canProceed(): Promise<boolean>;\n recordJobStart(): Promise<void>;\n recordJobCompletion(): Promise<void>;\n getNextAvailableTime(): Promise<Date>;\n setNextAvailableTime(date: Date): Promise<void>;\n clear(): Promise<void>;\n}\n\nexport interface RateLimiterOptions {\n readonly maxExecutions: number;\n readonly windowSizeInSeconds: number;\n}\n\nexport interface RateLimiterWithBackoffOptions extends RateLimiterOptions {\n readonly initialBackoffDelay?: number;\n readonly backoffMultiplier?: number;\n readonly maxBackoffDelay?: number;\n}\n",
|
|
16
16
|
"/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IRateLimiterStorage } from \"@workglow/storage\";\nimport { ILimiter, RateLimiterWithBackoffOptions } from \"./ILimiter\";\n\n/**\n * Base rate limiter implementation that uses a storage backend.\n * Manages request counts and delays to control job execution.\n */\nexport class RateLimiter implements ILimiter {\n protected readonly windowSizeInMilliseconds: number;\n protected currentBackoffDelay: number;\n protected readonly maxExecutions: number;\n protected readonly initialBackoffDelay: number;\n protected readonly backoffMultiplier: number;\n protected readonly maxBackoffDelay: number;\n\n constructor(\n protected readonly storage: IRateLimiterStorage,\n protected readonly queueName: string,\n {\n maxExecutions,\n windowSizeInSeconds,\n initialBackoffDelay = 1_000,\n backoffMultiplier = 2,\n maxBackoffDelay = 600_000, // 10 minutes\n }: RateLimiterWithBackoffOptions\n ) {\n if (maxExecutions <= 0) {\n throw new Error(\"maxExecutions must be greater than 0\");\n }\n if (windowSizeInSeconds <= 0) {\n throw new Error(\"windowSizeInSeconds must be greater than 0\");\n }\n if (initialBackoffDelay <= 0) {\n throw new Error(\"initialBackoffDelay must be greater than 0\");\n }\n if (backoffMultiplier <= 1) {\n throw new Error(\"backoffMultiplier must be greater than 1\");\n }\n if (maxBackoffDelay <= initialBackoffDelay) {\n throw new Error(\"maxBackoffDelay must be greater than initialBackoffDelay\");\n }\n\n this.windowSizeInMilliseconds = windowSizeInSeconds * 1000;\n this.maxExecutions = maxExecutions;\n this.initialBackoffDelay = initialBackoffDelay;\n this.backoffMultiplier = backoffMultiplier;\n this.maxBackoffDelay = maxBackoffDelay;\n this.currentBackoffDelay = initialBackoffDelay;\n }\n\n protected addJitter(base: number): number {\n // full jitter in [base, 2*base)\n return base + Math.random() * base;\n }\n\n protected increaseBackoff(): void {\n this.currentBackoffDelay = Math.min(\n this.currentBackoffDelay * this.backoffMultiplier,\n this.maxBackoffDelay\n );\n }\n\n /**\n * Checks if a job can proceed based on rate limiting rules.\n * @returns True if the job can proceed, false otherwise\n */\n async canProceed(): Promise<boolean> {\n // First check if the window allows more executions\n const windowStartTime = new Date(Date.now() - this.windowSizeInMilliseconds).toISOString();\n const attemptCount = await this.storage.getExecutionCount(this.queueName, windowStartTime);\n const canProceedNow = attemptCount < this.maxExecutions;\n\n // If the window allows more executions, clear any backoff and proceed\n if (canProceedNow) {\n // Clear any existing nextAvailableTime backoff since the window allows more executions\n const nextAvailableTime = await this.storage.getNextAvailableTime(this.queueName);\n if (nextAvailableTime && new Date(nextAvailableTime).getTime() > Date.now()) {\n // Clear the backoff by setting it to the past\n const pastTime = new Date(Date.now() - 1000);\n await this.storage.setNextAvailableTime(this.queueName, pastTime.toISOString());\n }\n this.currentBackoffDelay = this.initialBackoffDelay;\n return true;\n }\n\n // Window is full, check if there's a backoff delay\n const nextAvailableTime = await this.storage.getNextAvailableTime(this.queueName);\n if (nextAvailableTime && new Date(nextAvailableTime).getTime() > Date.now()) {\n this.increaseBackoff();\n return false;\n }\n\n // Window is full but no backoff delay, so we can't proceed\n this.increaseBackoff();\n return false;\n }\n\n /**\n * Records a new job attempt.\n */\n async recordJobStart(): Promise<void> {\n await this.storage.recordExecution(this.queueName);\n\n const windowStartTime = new Date(Date.now() - this.windowSizeInMilliseconds).toISOString();\n const attemptCount = await this.storage.getExecutionCount(this.queueName, windowStartTime);\n\n if (attemptCount >= this.maxExecutions) {\n const backoffExpires = new Date(Date.now() + this.addJitter(this.currentBackoffDelay));\n await this.setNextAvailableTime(backoffExpires);\n } else {\n // Window allows more executions, clear any existing nextAvailableTime by setting it to the past\n const nextAvailableTime = await this.storage.getNextAvailableTime(this.queueName);\n if (nextAvailableTime && new Date(nextAvailableTime).getTime() > Date.now()) {\n // Clear the backoff since the window now allows more executions\n // Set to a time in the past to effectively clear it\n const pastTime = new Date(Date.now() - 1000);\n await this.storage.setNextAvailableTime(this.queueName, pastTime.toISOString());\n }\n }\n }\n\n async recordJobCompletion(): Promise<void> {\n // Implementation can be no-op as completion doesn't affect rate limiting\n }\n\n /**\n * Retrieves the next available time for the specific queue.\n * @returns The next available time\n */\n async getNextAvailableTime(): Promise<Date> {\n // Get the time when the rate limit will allow the next job execution\n const oldestExecution = await this.storage.getOldestExecutionAtOffset(\n this.queueName,\n this.maxExecutions - 1\n );\n\n let rateLimitedTime = new Date();\n if (oldestExecution) {\n rateLimitedTime = new Date(oldestExecution);\n rateLimitedTime.setSeconds(\n rateLimitedTime.getSeconds() + this.windowSizeInMilliseconds / 1000\n );\n }\n\n // Get the next available time set externally, if any\n const nextAvailableStr = await this.storage.getNextAvailableTime(this.queueName);\n let nextAvailableTime = new Date();\n if (nextAvailableStr) {\n nextAvailableTime = new Date(nextAvailableStr);\n }\n\n // Return the later of the two times\n return nextAvailableTime > rateLimitedTime ? nextAvailableTime : rateLimitedTime;\n }\n\n /**\n * Sets the next available time for the specific queue.\n * @param date - The new next available time\n */\n async setNextAvailableTime(date: Date): Promise<void> {\n await this.storage.setNextAvailableTime(this.queueName, date.toISOString());\n }\n\n /**\n * Clears all rate limit entries for this queue.\n */\n async clear(): Promise<void> {\n await this.storage.clear(this.queueName);\n this.currentBackoffDelay = this.initialBackoffDelay;\n }\n}\n"
|
|
17
17
|
],
|
|
18
|
-
"mappings": "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",
|
|
19
|
-
"debugId": "
|
|
18
|
+
"mappings": "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",
|
|
19
|
+
"debugId": "93911FFD8A0112A464756E2164756E21",
|
|
20
20
|
"names": []
|
|
21
21
|
}
|
package/dist/bun.js
CHANGED
|
@@ -584,10 +584,14 @@ class JobQueueWorker {
|
|
|
584
584
|
} catch (err) {
|
|
585
585
|
const error = this.normalizeError(err);
|
|
586
586
|
if (error instanceof RetryableJobError) {
|
|
587
|
-
|
|
588
|
-
|
|
587
|
+
const currentJob = await this.getJob(job.id);
|
|
588
|
+
if (!currentJob) {
|
|
589
|
+
throw new JobNotFoundError(`Job ${job.id} not found`);
|
|
590
|
+
}
|
|
591
|
+
if (currentJob.runAttempts >= currentJob.maxRetries) {
|
|
592
|
+
await this.failJob(currentJob, new PermanentJobError("Max retries reached"));
|
|
589
593
|
} else {
|
|
590
|
-
await this.rescheduleJob(
|
|
594
|
+
await this.rescheduleJob(currentJob, error.retryDate);
|
|
591
595
|
}
|
|
592
596
|
} else {
|
|
593
597
|
await this.failJob(job, error);
|
|
@@ -667,6 +671,7 @@ class JobQueueWorker {
|
|
|
667
671
|
job.progress = 0;
|
|
668
672
|
job.progressMessage = "";
|
|
669
673
|
job.progressDetails = null;
|
|
674
|
+
job.runAttempts = (job.runAttempts ?? 0) + 1;
|
|
670
675
|
await this.storage.complete(this.classToStorage(job));
|
|
671
676
|
this.events.emit("job_retry", job.id, job.runAfter);
|
|
672
677
|
} catch (err) {
|
|
@@ -1380,4 +1385,4 @@ export {
|
|
|
1380
1385
|
AbortSignalJobError
|
|
1381
1386
|
};
|
|
1382
1387
|
|
|
1383
|
-
//# debugId=
|
|
1388
|
+
//# debugId=58283C807CBC28F064756E2164756E21
|