@workglow/job-queue 0.0.56 → 0.0.58
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/README.md +432 -306
- package/dist/browser.js +808 -509
- package/dist/browser.js.map +9 -8
- package/dist/bun.js +823 -823
- package/dist/bun.js.map +9 -10
- package/dist/common-server.d.ts +0 -2
- package/dist/common-server.d.ts.map +1 -1
- package/dist/common.d.ts +4 -3
- package/dist/common.d.ts.map +1 -1
- package/dist/job/Job.d.ts +3 -4
- package/dist/job/Job.d.ts.map +1 -1
- package/dist/job/JobQueueClient.d.ts +171 -0
- package/dist/job/JobQueueClient.d.ts.map +1 -0
- package/dist/job/JobQueueEventListeners.d.ts +1 -1
- package/dist/job/JobQueueEventListeners.d.ts.map +1 -1
- package/dist/job/JobQueueServer.d.ts +160 -0
- package/dist/job/JobQueueServer.d.ts.map +1 -0
- package/dist/job/JobQueueWorker.d.ts +157 -0
- package/dist/job/JobQueueWorker.d.ts.map +1 -0
- package/dist/limiter/RateLimiter.d.ts +49 -0
- package/dist/limiter/RateLimiter.d.ts.map +1 -0
- package/dist/node.js +823 -823
- package/dist/node.js.map +9 -10
- package/package.json +5 -13
- package/dist/job/IJobQueue.d.ts +0 -160
- package/dist/job/IJobQueue.d.ts.map +0 -1
- package/dist/job/JobQueue.d.ts +0 -272
- package/dist/job/JobQueue.d.ts.map +0 -1
- package/dist/limiter/InMemoryRateLimiter.d.ts +0 -32
- package/dist/limiter/InMemoryRateLimiter.d.ts.map +0 -1
- package/dist/limiter/PostgresRateLimiter.d.ts +0 -53
- package/dist/limiter/PostgresRateLimiter.d.ts.map +0 -1
- package/dist/limiter/SqliteRateLimiter.d.ts +0 -44
- package/dist/limiter/SqliteRateLimiter.d.ts.map +0 -1
package/dist/job/Job.d.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { JobStatus } from "
|
|
7
|
-
import type { JobQueue } from "./JobQueue";
|
|
6
|
+
import { JobStatus } from "@workglow/storage";
|
|
8
7
|
import type { JobProgressListener } from "./JobQueueEventListeners";
|
|
8
|
+
export { JobStatus };
|
|
9
9
|
/**
|
|
10
10
|
* Context for job execution
|
|
11
11
|
*/
|
|
@@ -63,12 +63,11 @@ export declare class Job<Input, Output> {
|
|
|
63
63
|
progress: number;
|
|
64
64
|
progressMessage: string;
|
|
65
65
|
progressDetails: Record<string, any> | null;
|
|
66
|
-
queue: JobQueue<Input, Output> | undefined;
|
|
67
66
|
constructor({ queueName, input, jobRunId, id, error, errorCode, fingerprint, output, maxRetries, createdAt, completedAt, status, deadlineAt, runAttempts, lastRanAt, runAfter, progress, progressMessage, progressDetails, }: JobConstructorParam<Input, Output>);
|
|
68
67
|
execute(input: Input, context: IJobExecuteContext): Promise<Output>;
|
|
69
68
|
private progressListeners;
|
|
70
69
|
/**
|
|
71
|
-
* Update the job's progress
|
|
70
|
+
* Update the job's progress (for direct execution without a worker)
|
|
72
71
|
* @param progress - Progress value between 0 and 100
|
|
73
72
|
* @param message - Optional progress message
|
|
74
73
|
* @param details - Optional progress details
|
package/dist/job/Job.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Job.d.ts","sourceRoot":"","sources":["../../src/job/Job.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"Job.d.ts","sourceRoot":"","sources":["../../src/job/Job.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { IQueueStorage, JobStatus, JobStorageFormat } from "@workglow/storage";
|
|
7
|
+
import { EventEmitter } from "@workglow/util";
|
|
8
|
+
import { Job } from "./Job";
|
|
9
|
+
import { JobError } from "./JobError";
|
|
10
|
+
import { JobProgressListener, JobQueueEventListener, JobQueueEventListeners, JobQueueEventParameters, JobQueueEvents } from "./JobQueueEventListeners";
|
|
11
|
+
import type { JobQueueServer } from "./JobQueueServer";
|
|
12
|
+
/**
|
|
13
|
+
* Handle returned when submitting a job, providing methods to interact with the job
|
|
14
|
+
*/
|
|
15
|
+
export interface JobHandle<Output> {
|
|
16
|
+
readonly id: unknown;
|
|
17
|
+
waitFor(): Promise<Output>;
|
|
18
|
+
abort(): Promise<void>;
|
|
19
|
+
onProgress(callback: JobProgressListener): () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Options for creating a JobQueueClient
|
|
23
|
+
*/
|
|
24
|
+
export interface JobQueueClientOptions<Input, Output> {
|
|
25
|
+
readonly storage: IQueueStorage<Input, Output>;
|
|
26
|
+
readonly queueName: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Client for submitting jobs and monitoring their progress.
|
|
30
|
+
* Connect to a JobQueueServer for same-process optimization,
|
|
31
|
+
* or use storage subscriptions for cross-process communication.
|
|
32
|
+
*/
|
|
33
|
+
export declare class JobQueueClient<Input, Output> {
|
|
34
|
+
readonly queueName: string;
|
|
35
|
+
protected readonly storage: IQueueStorage<Input, Output>;
|
|
36
|
+
protected readonly events: EventEmitter<JobQueueEventListeners<Input, Output>>;
|
|
37
|
+
protected server: JobQueueServer<Input, Output> | null;
|
|
38
|
+
protected storageUnsubscribe: (() => void) | null;
|
|
39
|
+
/**
|
|
40
|
+
* Map of job IDs to their pending promise resolvers
|
|
41
|
+
*/
|
|
42
|
+
protected readonly activeJobPromises: Map<unknown, Array<{
|
|
43
|
+
resolve: (value: Output) => void;
|
|
44
|
+
reject: (err: JobError) => void;
|
|
45
|
+
}>>;
|
|
46
|
+
/**
|
|
47
|
+
* Map of job IDs to their progress listeners
|
|
48
|
+
*/
|
|
49
|
+
protected readonly jobProgressListeners: Map<unknown, Set<JobProgressListener>>;
|
|
50
|
+
/**
|
|
51
|
+
* Last known progress state for each job
|
|
52
|
+
*/
|
|
53
|
+
protected readonly lastKnownProgress: Map<unknown, {
|
|
54
|
+
readonly progress: number;
|
|
55
|
+
readonly message: string;
|
|
56
|
+
readonly details: Record<string, unknown> | null;
|
|
57
|
+
}>;
|
|
58
|
+
constructor(options: JobQueueClientOptions<Input, Output>);
|
|
59
|
+
/**
|
|
60
|
+
* Attach to a local JobQueueServer for same-process event optimization.
|
|
61
|
+
* When attached, events flow directly from server without storage polling.
|
|
62
|
+
*/
|
|
63
|
+
attach(server: JobQueueServer<Input, Output>): void;
|
|
64
|
+
/**
|
|
65
|
+
* Detach from the current server
|
|
66
|
+
*/
|
|
67
|
+
detach(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Connect to storage for cross-process communication (when no local server).
|
|
70
|
+
* Uses storage subscriptions to receive job updates.
|
|
71
|
+
*/
|
|
72
|
+
connect(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Disconnect from storage subscriptions
|
|
75
|
+
*/
|
|
76
|
+
disconnect(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Submit a job to the queue
|
|
79
|
+
*/
|
|
80
|
+
submit(input: Input, options?: {
|
|
81
|
+
readonly jobRunId?: string;
|
|
82
|
+
readonly fingerprint?: string;
|
|
83
|
+
readonly maxRetries?: number;
|
|
84
|
+
readonly runAfter?: Date;
|
|
85
|
+
readonly deadlineAt?: Date;
|
|
86
|
+
}): Promise<JobHandle<Output>>;
|
|
87
|
+
/**
|
|
88
|
+
* Submit multiple jobs to the queue
|
|
89
|
+
*/
|
|
90
|
+
submitBatch(inputs: readonly Input[], options?: {
|
|
91
|
+
readonly jobRunId?: string;
|
|
92
|
+
readonly maxRetries?: number;
|
|
93
|
+
}): Promise<readonly JobHandle<Output>[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Get a job by ID
|
|
96
|
+
*/
|
|
97
|
+
getJob(id: unknown): Promise<Job<Input, Output> | undefined>;
|
|
98
|
+
/**
|
|
99
|
+
* Get jobs by run ID
|
|
100
|
+
*/
|
|
101
|
+
getJobsByRunId(runId: string): Promise<readonly Job<Input, Output>[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Peek at jobs in the queue
|
|
104
|
+
*/
|
|
105
|
+
peek(status?: JobStatus, num?: number): Promise<readonly Job<Input, Output>[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Get the size of the queue
|
|
108
|
+
*/
|
|
109
|
+
size(status?: JobStatus): Promise<number>;
|
|
110
|
+
/**
|
|
111
|
+
* Get the output for an input (if job completed)
|
|
112
|
+
*/
|
|
113
|
+
outputForInput(input: Input): Promise<Output | null>;
|
|
114
|
+
/**
|
|
115
|
+
* Wait for a job to complete
|
|
116
|
+
*/
|
|
117
|
+
waitFor(jobId: unknown): Promise<Output>;
|
|
118
|
+
/**
|
|
119
|
+
* Abort a job
|
|
120
|
+
*/
|
|
121
|
+
abort(jobId: unknown): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Abort all jobs in a job run
|
|
124
|
+
*/
|
|
125
|
+
abortJobRun(jobRunId: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Subscribe to progress updates for a specific job
|
|
128
|
+
*/
|
|
129
|
+
onJobProgress(jobId: unknown, listener: JobProgressListener): () => void;
|
|
130
|
+
on<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
131
|
+
off<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
132
|
+
once<Event extends JobQueueEvents>(event: Event, listener: JobQueueEventListener<Event>): void;
|
|
133
|
+
waitOn<Event extends JobQueueEvents>(event: Event): Promise<JobQueueEventParameters<Event, Input, Output>>;
|
|
134
|
+
/**
|
|
135
|
+
* Called by server when a job starts processing
|
|
136
|
+
* @internal
|
|
137
|
+
*/
|
|
138
|
+
handleJobStart(jobId: unknown): void;
|
|
139
|
+
/**
|
|
140
|
+
* Called by server when a job completes
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
handleJobComplete(jobId: unknown, output: Output): void;
|
|
144
|
+
/**
|
|
145
|
+
* Called by server when a job fails
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
handleJobError(jobId: unknown, error: string, errorCode?: string): void;
|
|
149
|
+
/**
|
|
150
|
+
* Called by server when a job is disabled
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
handleJobDisabled(jobId: unknown): void;
|
|
154
|
+
/**
|
|
155
|
+
* Called by server when a job is retried
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
handleJobRetry(jobId: unknown, runAfter: Date): void;
|
|
159
|
+
/**
|
|
160
|
+
* Called by server when job progress updates
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
handleJobProgress(jobId: unknown, progress: number, message: string, details: Record<string, unknown> | null): void;
|
|
164
|
+
private createJobHandle;
|
|
165
|
+
private cleanupJob;
|
|
166
|
+
private handleStorageChange;
|
|
167
|
+
protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output>;
|
|
168
|
+
protected buildErrorFromJob(job: Job<Input, Output>): JobError;
|
|
169
|
+
protected buildErrorFromCode(message: string, errorCode?: string): JobError;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=JobQueueClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobQueueClient.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobQueueEventListeners.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueEventListeners.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"JobQueueEventListeners.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueEventListeners.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAAC,KAAK,EAAE,MAAM,IAAI;IAClD,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;IACvE,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACtE,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAChC,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEpE,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,cAAc,IAAI,sBAAsB,CACtF,GAAG,EACH,GAAG,CACJ,CAAC,KAAK,CAAC,CAAC;AAET,MAAM,MAAM,uBAAuB,CAAC,KAAK,SAAS,cAAc,EAAE,KAAK,EAAE,MAAM,IAAI,eAAe,CAChG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,EACrC,KAAK,CACN,CAAC;AACF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAChC,IAAI,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { IQueueStorage, JobStorageFormat } from "@workglow/storage";
|
|
7
|
+
import { EventEmitter } from "@workglow/util";
|
|
8
|
+
import { ILimiter } from "../limiter/ILimiter";
|
|
9
|
+
import { Job, JobConstructorParam } from "./Job";
|
|
10
|
+
import { JobQueueClient } from "./JobQueueClient";
|
|
11
|
+
import { JobQueueWorker } from "./JobQueueWorker";
|
|
12
|
+
/**
|
|
13
|
+
* Statistics tracked for the job queue
|
|
14
|
+
*/
|
|
15
|
+
export interface JobQueueStats {
|
|
16
|
+
readonly totalJobs: number;
|
|
17
|
+
readonly completedJobs: number;
|
|
18
|
+
readonly failedJobs: number;
|
|
19
|
+
readonly abortedJobs: number;
|
|
20
|
+
readonly retriedJobs: number;
|
|
21
|
+
readonly disabledJobs: number;
|
|
22
|
+
readonly averageProcessingTime?: number;
|
|
23
|
+
readonly lastUpdateTime: Date;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Events emitted by JobQueueServer
|
|
27
|
+
*/
|
|
28
|
+
export type JobQueueServerEventListeners<Input, Output> = {
|
|
29
|
+
server_start: (queueName: string) => void;
|
|
30
|
+
server_stop: (queueName: string) => void;
|
|
31
|
+
stats_update: (queueName: string, stats: JobQueueStats) => void;
|
|
32
|
+
job_start: (queueName: string, jobId: unknown) => void;
|
|
33
|
+
job_complete: (queueName: string, jobId: unknown, output: Output) => void;
|
|
34
|
+
job_error: (queueName: string, jobId: unknown, error: string) => void;
|
|
35
|
+
job_disabled: (queueName: string, jobId: unknown) => void;
|
|
36
|
+
job_retry: (queueName: string, jobId: unknown, runAfter: Date) => void;
|
|
37
|
+
job_progress: (queueName: string, jobId: unknown, progress: number, message: string, details: Record<string, unknown> | null) => void;
|
|
38
|
+
};
|
|
39
|
+
export type JobQueueServerEvents = keyof JobQueueServerEventListeners<unknown, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* Options for creating a JobQueueServer
|
|
42
|
+
*/
|
|
43
|
+
export interface JobQueueServerOptions<Input, Output> {
|
|
44
|
+
readonly storage: IQueueStorage<Input, Output>;
|
|
45
|
+
readonly queueName: string;
|
|
46
|
+
readonly limiter?: ILimiter;
|
|
47
|
+
readonly workerCount?: number;
|
|
48
|
+
readonly pollIntervalMs?: number;
|
|
49
|
+
readonly deleteAfterCompletionMs?: number;
|
|
50
|
+
readonly deleteAfterFailureMs?: number;
|
|
51
|
+
readonly deleteAfterDisabledMs?: number;
|
|
52
|
+
readonly cleanupIntervalMs?: number;
|
|
53
|
+
}
|
|
54
|
+
type JobClass<Input, Output> = new (param: JobConstructorParam<Input, Output>) => Job<Input, Output>;
|
|
55
|
+
/**
|
|
56
|
+
* Server that coordinates multiple workers and manages the job queue lifecycle.
|
|
57
|
+
* Handles stuck job recovery, cleanup, and aggregates statistics.
|
|
58
|
+
*/
|
|
59
|
+
export declare class JobQueueServer<Input, Output, QueueJob extends Job<Input, Output> = Job<Input, Output>> {
|
|
60
|
+
readonly queueName: string;
|
|
61
|
+
protected readonly storage: IQueueStorage<Input, Output>;
|
|
62
|
+
protected readonly jobClass: JobClass<Input, Output>;
|
|
63
|
+
protected readonly limiter: ILimiter;
|
|
64
|
+
protected readonly workerCount: number;
|
|
65
|
+
protected readonly pollIntervalMs: number;
|
|
66
|
+
protected readonly deleteAfterCompletionMs?: number;
|
|
67
|
+
protected readonly deleteAfterFailureMs?: number;
|
|
68
|
+
protected readonly deleteAfterDisabledMs?: number;
|
|
69
|
+
protected readonly cleanupIntervalMs: number;
|
|
70
|
+
protected readonly events: EventEmitter<JobQueueServerEventListeners<Input, Output>>;
|
|
71
|
+
protected readonly workers: JobQueueWorker<Input, Output, QueueJob>[];
|
|
72
|
+
protected readonly clients: Set<JobQueueClient<Input, Output>>;
|
|
73
|
+
protected running: boolean;
|
|
74
|
+
protected cleanupTimer: ReturnType<typeof setTimeout> | null;
|
|
75
|
+
protected stats: JobQueueStats;
|
|
76
|
+
constructor(jobClass: JobClass<Input, Output>, options: JobQueueServerOptions<Input, Output>);
|
|
77
|
+
/**
|
|
78
|
+
* Start the server and all workers
|
|
79
|
+
*/
|
|
80
|
+
start(): Promise<this>;
|
|
81
|
+
/**
|
|
82
|
+
* Stop the server and all workers
|
|
83
|
+
*/
|
|
84
|
+
stop(): Promise<this>;
|
|
85
|
+
/**
|
|
86
|
+
* Get the current queue statistics
|
|
87
|
+
*/
|
|
88
|
+
getStats(): JobQueueStats;
|
|
89
|
+
/**
|
|
90
|
+
* Get the storage instance (for client connection)
|
|
91
|
+
*/
|
|
92
|
+
getStorage(): IQueueStorage<Input, Output>;
|
|
93
|
+
/**
|
|
94
|
+
* Scale the number of workers
|
|
95
|
+
*/
|
|
96
|
+
scaleWorkers(count: number): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Check if the server is running
|
|
99
|
+
*/
|
|
100
|
+
isRunning(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get the number of workers
|
|
103
|
+
*/
|
|
104
|
+
getWorkerCount(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Add a client for same-process event forwarding
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
addClient(client: JobQueueClient<Input, Output>): void;
|
|
110
|
+
/**
|
|
111
|
+
* Remove a client
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
removeClient(client: JobQueueClient<Input, Output>): void;
|
|
115
|
+
on<Event extends JobQueueServerEvents>(event: Event, listener: JobQueueServerEventListeners<Input, Output>[Event]): void;
|
|
116
|
+
off<Event extends JobQueueServerEvents>(event: Event, listener: JobQueueServerEventListeners<Input, Output>[Event]): void;
|
|
117
|
+
/**
|
|
118
|
+
* Initialize workers
|
|
119
|
+
*/
|
|
120
|
+
protected initializeWorkers(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Create a new worker and wire up event forwarding
|
|
123
|
+
*/
|
|
124
|
+
protected createWorker(): JobQueueWorker<Input, Output, QueueJob>;
|
|
125
|
+
/**
|
|
126
|
+
* Forward events to all attached clients
|
|
127
|
+
*/
|
|
128
|
+
protected forwardToClients(method: "handleJobStart", jobId: unknown): void;
|
|
129
|
+
protected forwardToClients(method: "handleJobComplete", jobId: unknown, output: Output): void;
|
|
130
|
+
protected forwardToClients(method: "handleJobError", jobId: unknown, error: string, errorCode?: string): void;
|
|
131
|
+
protected forwardToClients(method: "handleJobDisabled", jobId: unknown): void;
|
|
132
|
+
protected forwardToClients(method: "handleJobRetry", jobId: unknown, runAfter: Date): void;
|
|
133
|
+
protected forwardToClients(method: "handleJobProgress", jobId: unknown, progress: number, message: string, details: Record<string, unknown> | null): void;
|
|
134
|
+
/**
|
|
135
|
+
* Update average processing time from all workers
|
|
136
|
+
*/
|
|
137
|
+
protected updateAverageProcessingTime(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Start the cleanup loop
|
|
140
|
+
*/
|
|
141
|
+
protected startCleanupLoop(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Clean up completed/failed jobs based on TTL settings
|
|
144
|
+
*/
|
|
145
|
+
protected cleanupJobs(): Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Fix stuck jobs from previous server runs
|
|
148
|
+
*/
|
|
149
|
+
protected fixupJobs(): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* Convert storage format to Job class
|
|
152
|
+
*/
|
|
153
|
+
protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output>;
|
|
154
|
+
/**
|
|
155
|
+
* Convert Job class to storage format
|
|
156
|
+
*/
|
|
157
|
+
protected classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output>;
|
|
158
|
+
}
|
|
159
|
+
export {};
|
|
160
|
+
//# sourceMappingURL=JobQueueServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobQueueServer.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { IQueueStorage, JobStorageFormat } from "@workglow/storage";
|
|
7
|
+
import { EventEmitter } from "@workglow/util";
|
|
8
|
+
import { ILimiter } from "../limiter/ILimiter";
|
|
9
|
+
import { Job, JobConstructorParam } from "./Job";
|
|
10
|
+
import { JobError } from "./JobError";
|
|
11
|
+
/**
|
|
12
|
+
* Events emitted by JobQueueWorker
|
|
13
|
+
*/
|
|
14
|
+
export type JobQueueWorkerEventListeners<Input, Output> = {
|
|
15
|
+
job_start: (jobId: unknown) => void;
|
|
16
|
+
job_complete: (jobId: unknown, output: Output) => void;
|
|
17
|
+
job_error: (jobId: unknown, error: string, errorCode?: string) => void;
|
|
18
|
+
job_disabled: (jobId: unknown) => void;
|
|
19
|
+
job_retry: (jobId: unknown, runAfter: Date) => void;
|
|
20
|
+
job_progress: (jobId: unknown, progress: number, message: string, details: Record<string, unknown> | null) => void;
|
|
21
|
+
worker_start: () => void;
|
|
22
|
+
worker_stop: () => void;
|
|
23
|
+
};
|
|
24
|
+
export type JobQueueWorkerEvents = keyof JobQueueWorkerEventListeners<unknown, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Options for creating a JobQueueWorker
|
|
27
|
+
*/
|
|
28
|
+
export interface JobQueueWorkerOptions<Input, Output> {
|
|
29
|
+
readonly storage: IQueueStorage<Input, Output>;
|
|
30
|
+
readonly queueName: string;
|
|
31
|
+
readonly limiter?: ILimiter;
|
|
32
|
+
readonly pollIntervalMs?: number;
|
|
33
|
+
}
|
|
34
|
+
type JobClass<Input, Output> = new (param: JobConstructorParam<Input, Output>) => Job<Input, Output>;
|
|
35
|
+
/**
|
|
36
|
+
* Worker that processes jobs from the queue.
|
|
37
|
+
* Reports progress and completion back to storage.
|
|
38
|
+
*/
|
|
39
|
+
export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, Output> = Job<Input, Output>> {
|
|
40
|
+
readonly queueName: string;
|
|
41
|
+
readonly workerId: string;
|
|
42
|
+
protected readonly storage: IQueueStorage<Input, Output>;
|
|
43
|
+
protected readonly jobClass: JobClass<Input, Output>;
|
|
44
|
+
protected readonly limiter: ILimiter;
|
|
45
|
+
protected readonly pollIntervalMs: number;
|
|
46
|
+
protected readonly events: EventEmitter<JobQueueWorkerEventListeners<Input, Output>>;
|
|
47
|
+
protected running: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Abort controllers for active jobs
|
|
50
|
+
*/
|
|
51
|
+
protected readonly activeJobAbortControllers: Map<unknown, AbortController>;
|
|
52
|
+
/**
|
|
53
|
+
* Processing times for statistics
|
|
54
|
+
*/
|
|
55
|
+
protected readonly processingTimes: Map<unknown, number>;
|
|
56
|
+
constructor(jobClass: JobClass<Input, Output>, options: JobQueueWorkerOptions<Input, Output>);
|
|
57
|
+
/**
|
|
58
|
+
* Start the worker processing loop
|
|
59
|
+
*/
|
|
60
|
+
start(): Promise<this>;
|
|
61
|
+
/**
|
|
62
|
+
* Stop the worker and abort any active jobs
|
|
63
|
+
*/
|
|
64
|
+
stop(): Promise<this>;
|
|
65
|
+
/**
|
|
66
|
+
* Process a single job manually (useful for testing or manual control)
|
|
67
|
+
*/
|
|
68
|
+
processNext(): Promise<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Check if the worker is currently running
|
|
71
|
+
*/
|
|
72
|
+
isRunning(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Get the number of active jobs being processed
|
|
75
|
+
*/
|
|
76
|
+
getActiveJobCount(): number;
|
|
77
|
+
/**
|
|
78
|
+
* Get average processing time
|
|
79
|
+
*/
|
|
80
|
+
getAverageProcessingTime(): number | undefined;
|
|
81
|
+
on<Event extends JobQueueWorkerEvents>(event: Event, listener: JobQueueWorkerEventListeners<Input, Output>[Event]): void;
|
|
82
|
+
off<Event extends JobQueueWorkerEvents>(event: Event, listener: JobQueueWorkerEventListeners<Input, Output>[Event]): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get the next job from the queue
|
|
85
|
+
*/
|
|
86
|
+
protected next(): Promise<QueueJob | undefined>;
|
|
87
|
+
/**
|
|
88
|
+
* Main job processing loop
|
|
89
|
+
*/
|
|
90
|
+
protected processJobs(): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Check for jobs that have been marked for abort and trigger their abort controllers
|
|
93
|
+
*/
|
|
94
|
+
protected checkForAbortingJobs(): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Process a single job
|
|
97
|
+
*/
|
|
98
|
+
protected processSingleJob(job: Job<Input, Output>): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Execute a job with the provided abort signal
|
|
101
|
+
*/
|
|
102
|
+
protected executeJob(job: Job<Input, Output>, signal: AbortSignal): Promise<Output>;
|
|
103
|
+
/**
|
|
104
|
+
* Update progress for a job
|
|
105
|
+
*/
|
|
106
|
+
protected updateProgress(jobId: unknown, progress: number, message?: string, details?: Record<string, unknown> | null): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Mark a job as completed
|
|
109
|
+
*/
|
|
110
|
+
protected completeJob(job: Job<Input, Output>, output?: Output): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Mark a job as failed
|
|
113
|
+
*/
|
|
114
|
+
protected failJob(job: Job<Input, Output>, error: JobError): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Mark a job as disabled
|
|
117
|
+
*/
|
|
118
|
+
protected disableJob(job: Job<Input, Output>): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Reschedule a job for retry
|
|
121
|
+
*/
|
|
122
|
+
protected rescheduleJob(job: Job<Input, Output>, retryDate?: Date): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Create an abort controller for a job
|
|
125
|
+
*/
|
|
126
|
+
protected createAbortController(jobId: unknown): AbortController;
|
|
127
|
+
/**
|
|
128
|
+
* Handle job abort
|
|
129
|
+
*/
|
|
130
|
+
protected handleAbort(jobId: unknown): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Get a job by ID
|
|
133
|
+
*/
|
|
134
|
+
protected getJob(id: unknown): Promise<Job<Input, Output> | undefined>;
|
|
135
|
+
/**
|
|
136
|
+
* Validate job state before processing
|
|
137
|
+
*/
|
|
138
|
+
protected validateJobState(job: Job<Input, Output>): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Normalize errors into JobError instances
|
|
141
|
+
*/
|
|
142
|
+
protected normalizeError(err: unknown): JobError;
|
|
143
|
+
/**
|
|
144
|
+
* Clean up job state after completion/failure
|
|
145
|
+
*/
|
|
146
|
+
protected cleanupJob(jobId: unknown): void;
|
|
147
|
+
/**
|
|
148
|
+
* Convert storage format to Job class
|
|
149
|
+
*/
|
|
150
|
+
protected storageToClass(details: JobStorageFormat<Input, Output>): Job<Input, Output>;
|
|
151
|
+
/**
|
|
152
|
+
* Convert Job class to storage format
|
|
153
|
+
*/
|
|
154
|
+
protected classToStorage(job: Job<Input, Output>): JobStorageFormat<Input, Output>;
|
|
155
|
+
}
|
|
156
|
+
export {};
|
|
157
|
+
//# sourceMappingURL=JobQueueWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobQueueWorker.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { IRateLimiterStorage } from "@workglow/storage";
|
|
7
|
+
import { ILimiter, RateLimiterWithBackoffOptions } from "./ILimiter";
|
|
8
|
+
/**
|
|
9
|
+
* Base rate limiter implementation that uses a storage backend.
|
|
10
|
+
* Manages request counts and delays to control job execution.
|
|
11
|
+
*/
|
|
12
|
+
export declare class RateLimiter implements ILimiter {
|
|
13
|
+
protected readonly storage: IRateLimiterStorage;
|
|
14
|
+
protected readonly queueName: string;
|
|
15
|
+
protected readonly windowSizeInMilliseconds: number;
|
|
16
|
+
protected currentBackoffDelay: number;
|
|
17
|
+
protected readonly maxExecutions: number;
|
|
18
|
+
protected readonly initialBackoffDelay: number;
|
|
19
|
+
protected readonly backoffMultiplier: number;
|
|
20
|
+
protected readonly maxBackoffDelay: number;
|
|
21
|
+
constructor(storage: IRateLimiterStorage, queueName: string, { maxExecutions, windowSizeInSeconds, initialBackoffDelay, backoffMultiplier, maxBackoffDelay, }: RateLimiterWithBackoffOptions);
|
|
22
|
+
protected addJitter(base: number): number;
|
|
23
|
+
protected increaseBackoff(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Checks if a job can proceed based on rate limiting rules.
|
|
26
|
+
* @returns True if the job can proceed, false otherwise
|
|
27
|
+
*/
|
|
28
|
+
canProceed(): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Records a new job attempt.
|
|
31
|
+
*/
|
|
32
|
+
recordJobStart(): Promise<void>;
|
|
33
|
+
recordJobCompletion(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Retrieves the next available time for the specific queue.
|
|
36
|
+
* @returns The next available time
|
|
37
|
+
*/
|
|
38
|
+
getNextAvailableTime(): Promise<Date>;
|
|
39
|
+
/**
|
|
40
|
+
* Sets the next available time for the specific queue.
|
|
41
|
+
* @param date - The new next available time
|
|
42
|
+
*/
|
|
43
|
+
setNextAvailableTime(date: Date): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Clears all rate limit entries for this queue.
|
|
46
|
+
*/
|
|
47
|
+
clear(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=RateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/limiter/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAErE;;;GAGG;AACH,qBAAa,WAAY,YAAW,QAAQ;IASxC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,mBAAmB;IAC/C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM;IATtC,SAAS,CAAC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IACpD,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IACzC,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;gBAGtB,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAE,MAAM,EACpC,EACE,aAAa,EACb,mBAAmB,EACnB,mBAA2B,EAC3B,iBAAqB,EACrB,eAAyB,GAC1B,EAAE,6BAA6B;IA0BlC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKzC,SAAS,CAAC,eAAe,IAAI,IAAI;IAOjC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IA+BpC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1C;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3C;;;OAGG;IACG,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|