@workglow/job-queue 0.2.23 → 0.2.25
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 +131 -25
- package/dist/browser.js.map +5 -5
- package/dist/bun.js +131 -25
- package/dist/bun.js.map +5 -5
- package/dist/job/JobQueueClient.d.ts +24 -3
- package/dist/job/JobQueueClient.d.ts.map +1 -1
- package/dist/job/JobQueueServer.d.ts +25 -1
- package/dist/job/JobQueueServer.d.ts.map +1 -1
- package/dist/job/JobQueueWorker.d.ts +90 -7
- package/dist/job/JobQueueWorker.d.ts.map +1 -1
- package/dist/node.js +131 -25
- package/dist/node.js.map +5 -5
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobQueueClient.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueClient.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"JobQueueClient.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,11 @@ export interface JobQueueServerOptions<Input, Output> {
|
|
|
49
49
|
readonly deleteAfterFailureMs?: number;
|
|
50
50
|
readonly deleteAfterDisabledMs?: number;
|
|
51
51
|
readonly cleanupIntervalMs?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Max time each worker's `stop()` waits for in-flight jobs before forcing aborts.
|
|
54
|
+
* Defaults to 30s. Set to 0 to abort immediately.
|
|
55
|
+
*/
|
|
56
|
+
readonly stopTimeoutMs?: number;
|
|
52
57
|
}
|
|
53
58
|
/**
|
|
54
59
|
* Server that coordinates multiple workers and manages the job queue lifecycle.
|
|
@@ -65,6 +70,7 @@ export declare class JobQueueServer<Input, Output, QueueJob extends Job<Input, O
|
|
|
65
70
|
protected readonly deleteAfterFailureMs?: number;
|
|
66
71
|
protected readonly deleteAfterDisabledMs?: number;
|
|
67
72
|
protected readonly cleanupIntervalMs: number;
|
|
73
|
+
protected readonly stopTimeoutMs?: number;
|
|
68
74
|
protected readonly events: EventEmitter<JobQueueServerEventListeners<Input, Output>>;
|
|
69
75
|
protected readonly workers: JobQueueWorker<Input, Output, QueueJob>[];
|
|
70
76
|
protected readonly clients: Set<JobQueueClient<Input, Output>>;
|
|
@@ -77,6 +83,11 @@ export declare class JobQueueServer<Input, Output, QueueJob extends Job<Input, O
|
|
|
77
83
|
* Start the server and all workers
|
|
78
84
|
*/
|
|
79
85
|
start(): Promise<this>;
|
|
86
|
+
/**
|
|
87
|
+
* True if any delete-after-X TTL is set to a positive value.
|
|
88
|
+
* When false, the cleanup loop would be a pure no-op and is skipped.
|
|
89
|
+
*/
|
|
90
|
+
private hasRetentionTtls;
|
|
80
91
|
/**
|
|
81
92
|
* Stop the server and all workers
|
|
82
93
|
*/
|
|
@@ -113,8 +124,21 @@ export declare class JobQueueServer<Input, Output, QueueJob extends Job<Input, O
|
|
|
113
124
|
removeClient(client: JobQueueClient<Input, Output>): void;
|
|
114
125
|
/**
|
|
115
126
|
* Wake all idle workers so they check for new jobs immediately.
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
notifyWorkers(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Called by an attached client immediately after a job is inserted into storage,
|
|
132
|
+
* so the worker can pick it up without waiting for the poll interval.
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
handleJobAdded(_jobId: unknown): void;
|
|
136
|
+
/**
|
|
137
|
+
* Fire the abort controller for the given job on whichever worker is running it.
|
|
138
|
+
* Returns true if any worker handled the abort locally.
|
|
139
|
+
* @internal
|
|
116
140
|
*/
|
|
117
|
-
|
|
141
|
+
abortJob(jobId: unknown): boolean;
|
|
118
142
|
on<Event extends JobQueueServerEvents>(event: Event, listener: JobQueueServerEventListeners<Input, Output>[Event]): void;
|
|
119
143
|
off<Event extends JobQueueServerEvents>(event: Event, listener: JobQueueServerEventListeners<Input, Output>[Event]): void;
|
|
120
144
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobQueueServer.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAa,gBAAgB,EAAsB,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"JobQueueServer.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,6 +35,11 @@ export interface JobQueueWorkerOptions<Input, Output> {
|
|
|
35
35
|
* Use a persistent ID if you want the worker to reclaim its own jobs after restart.
|
|
36
36
|
*/
|
|
37
37
|
readonly workerId?: string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Max time `stop()` waits for in-flight jobs to finish before forcing aborts.
|
|
40
|
+
* Defaults to 30s. Set to 0 to abort immediately.
|
|
41
|
+
*/
|
|
42
|
+
readonly stopTimeoutMs?: number;
|
|
38
43
|
}
|
|
39
44
|
/**
|
|
40
45
|
* Worker that processes jobs from the queue.
|
|
@@ -47,14 +52,40 @@ export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, O
|
|
|
47
52
|
protected readonly jobClass: JobClass<Input, Output>;
|
|
48
53
|
protected readonly limiter: ILimiter;
|
|
49
54
|
protected readonly pollIntervalMs: number;
|
|
55
|
+
protected readonly stopTimeoutMs: number;
|
|
50
56
|
protected readonly events: EventEmitter<JobQueueWorkerEventListeners<Input, Output>>;
|
|
51
57
|
protected running: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Tracks in-flight job executions for drain-on-stop.
|
|
60
|
+
* Each entry's promise resolves (never rejects) when the job settles
|
|
61
|
+
* (complete / fail / retry / abort).
|
|
62
|
+
*/
|
|
63
|
+
private readonly inFlight;
|
|
52
64
|
/**
|
|
53
65
|
* Resolve function for the idle wait promise.
|
|
54
66
|
* When set, the worker is idle and waiting for either a notification or poll timeout.
|
|
55
67
|
*/
|
|
56
68
|
private wakeResolve;
|
|
57
69
|
private wakeTimer;
|
|
70
|
+
/**
|
|
71
|
+
* Set when {@link notify} fires while the worker is not yet idle. The next
|
|
72
|
+
* {@link waitForWakeOrTimeout} call consumes it and returns immediately
|
|
73
|
+
* instead of sleeping. Without this flag, a notify that arrives during
|
|
74
|
+
* `processJobs`'s pre-idle awaits (e.g. while `storage.next` and
|
|
75
|
+
* `storage.peek` are in flight) would be dropped on the floor and the
|
|
76
|
+
* worker would sleep for the full poll interval despite there being work
|
|
77
|
+
* to do — observed under load on IndexedDb.
|
|
78
|
+
*/
|
|
79
|
+
private wakePending;
|
|
80
|
+
/**
|
|
81
|
+
* Promise for the running `processJobs` loop. Captured in {@link start} so
|
|
82
|
+
* {@link stop} can await actual loop exit instead of returning while the
|
|
83
|
+
* loop is still suspended mid-iteration. Without this, a loop parked in
|
|
84
|
+
* `await this.next()` could resume after stop returned and claim a job
|
|
85
|
+
* that was submitted after stop — starting `processSingleJob` on a worker
|
|
86
|
+
* that's no longer running.
|
|
87
|
+
*/
|
|
88
|
+
private loopPromise;
|
|
58
89
|
/**
|
|
59
90
|
* Abort controllers for active jobs
|
|
60
91
|
*/
|
|
@@ -68,13 +99,22 @@ export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, O
|
|
|
68
99
|
* Start the worker processing loop
|
|
69
100
|
*/
|
|
70
101
|
start(): Promise<this>;
|
|
102
|
+
/**
|
|
103
|
+
* If this worker is currently processing the given job, fire its abort controller
|
|
104
|
+
* immediately and return true. Returns false if the job isn't active on this worker.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
requestAbort(jobId: unknown): boolean;
|
|
71
108
|
/**
|
|
72
109
|
* Wake the worker from idle sleep so it checks for jobs immediately.
|
|
73
|
-
*
|
|
110
|
+
* If the worker is not yet idle, latches a pending-wake flag that the next
|
|
111
|
+
* {@link waitForWakeOrTimeout} call consumes — so wake notifications that
|
|
112
|
+
* race with worker startup or mid-iteration awaits are not lost.
|
|
74
113
|
*/
|
|
75
114
|
notify(): void;
|
|
76
115
|
/**
|
|
77
|
-
* Stop the worker
|
|
116
|
+
* Stop the worker, draining in-flight jobs up to {@link stopTimeoutMs}
|
|
117
|
+
* before aborting anything still running.
|
|
78
118
|
*/
|
|
79
119
|
stop(): Promise<this>;
|
|
80
120
|
/**
|
|
@@ -115,11 +155,18 @@ export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, O
|
|
|
115
155
|
private getIdleDelay;
|
|
116
156
|
/**
|
|
117
157
|
* Wait for either a {@link notify} call or the given timeout,
|
|
118
|
-
* whichever comes first.
|
|
158
|
+
* whichever comes first. Consumes any pending wake latched while the worker
|
|
159
|
+
* was not yet idle (see {@link wakePending}) — returns immediately in that
|
|
160
|
+
* case rather than sleeping.
|
|
119
161
|
*/
|
|
120
162
|
private waitForWakeOrTimeout;
|
|
121
163
|
/**
|
|
122
|
-
* Check for jobs that have been marked for abort and trigger their abort controllers
|
|
164
|
+
* Check for jobs that have been marked for abort and trigger their abort controllers.
|
|
165
|
+
*
|
|
166
|
+
* Only relevant for jobs running on THIS worker (we have an abort controller
|
|
167
|
+
* registered for them). When no jobs are active, the peek result is irrelevant
|
|
168
|
+
* — skip the storage round-trip entirely. Important for battery life on
|
|
169
|
+
* same-process deployments (browser/mobile) where workers spend most time idle.
|
|
123
170
|
*/
|
|
124
171
|
protected checkForAbortingJobs(): Promise<void>;
|
|
125
172
|
/**
|
|
@@ -131,7 +178,12 @@ export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, O
|
|
|
131
178
|
*/
|
|
132
179
|
protected executeJob(job: Job<Input, Output>, signal: AbortSignal): Promise<Output>;
|
|
133
180
|
/**
|
|
134
|
-
* Update progress for a job
|
|
181
|
+
* Update progress for a job.
|
|
182
|
+
*
|
|
183
|
+
* Mid-job progress is delivered in-memory via the `job_progress` event;
|
|
184
|
+
* storage is only touched at terminal transitions (complete / fail / retry).
|
|
185
|
+
* Cross-process observers therefore see state transitions but not fine-grained
|
|
186
|
+
* progress — subscribe to an attached `JobQueueClient` for that.
|
|
135
187
|
*/
|
|
136
188
|
protected updateProgress(jobId: unknown, progress: number, message?: string, details?: Record<string, unknown> | null): Promise<void>;
|
|
137
189
|
/**
|
|
@@ -146,16 +198,47 @@ export declare class JobQueueWorker<Input, Output, QueueJob extends Job<Input, O
|
|
|
146
198
|
* Mark a job as disabled
|
|
147
199
|
*/
|
|
148
200
|
protected disableJob(job: Job<Input, Output>): Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* Release a job that {@link next} just claimed but that we won't process
|
|
203
|
+
* because the worker was stopped mid-claim. Resets the row to PENDING so
|
|
204
|
+
* the next started worker can pick it up. `fixupJobs()` would otherwise
|
|
205
|
+
* skip it (it ignores rows owned by current-server worker IDs).
|
|
206
|
+
*
|
|
207
|
+
* Uses `storage.release()` rather than `storage.complete()` so the retry
|
|
208
|
+
* budget isn't burned: the worker never actually attempted execution.
|
|
209
|
+
*/
|
|
210
|
+
protected releaseClaimedJob(job: Job<Input, Output>): Promise<void>;
|
|
149
211
|
/**
|
|
150
212
|
* Reschedule a job for retry
|
|
151
213
|
*/
|
|
152
214
|
protected rescheduleJob(job: Job<Input, Output>, retryDate?: Date): Promise<void>;
|
|
153
215
|
/**
|
|
154
|
-
* Create an abort controller for a job
|
|
216
|
+
* Create an abort controller for a job.
|
|
217
|
+
*
|
|
218
|
+
* The job MUST already be registered in {@link inFlight} — this enforces
|
|
219
|
+
* the invariant that `activeJobAbortControllers ⊆ inFlight`, which
|
|
220
|
+
* {@link handleAbort} relies on to decide whether `processSingleJob` is
|
|
221
|
+
* still on the hook for the terminal write. Calling this from any path
|
|
222
|
+
* other than `processSingleJob` (which registers `inFlight` first) is a
|
|
223
|
+
* programming error.
|
|
155
224
|
*/
|
|
156
225
|
protected createAbortController(jobId: unknown): AbortController;
|
|
157
226
|
/**
|
|
158
|
-
* Handle job abort
|
|
227
|
+
* Handle job abort.
|
|
228
|
+
*
|
|
229
|
+
* Two callers fire the controller and reach this listener:
|
|
230
|
+
* 1. `requestAbort` — same-process abort while the job is in flight here.
|
|
231
|
+
* 2. `checkForAbortingJobs` — cross-process abort observed via storage poll.
|
|
232
|
+
*
|
|
233
|
+
* In both cases, if processSingleJob is still running this job locally,
|
|
234
|
+
* the abort signal will propagate into the user task and processSingleJob's
|
|
235
|
+
* own catch path will write the terminal state. We must not race it: doing
|
|
236
|
+
* so duplicates the `job_error` emit and, worse, can clobber a successful
|
|
237
|
+
* `completeJob` that won the race (the COMPLETED→FAILED overwrite bug).
|
|
238
|
+
*
|
|
239
|
+
* If the job is no longer in flight here, it has already settled — recheck
|
|
240
|
+
* storage and only write FAILED for non-terminal states (i.e. an ABORTING
|
|
241
|
+
* row left over from a cross-process abort that this worker never picked up).
|
|
159
242
|
*/
|
|
160
243
|
protected handleAbort(jobId: unknown): Promise<void>;
|
|
161
244
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobQueueWorker.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueWorker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAa,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EACL,YAAY,EAMb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAGL,QAAQ,EAIT,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,MAAM,MAAM,4BAA4B,CAAC,KAAK,EAAE,MAAM,IAAI;IACxD,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC;IACpD,YAAY,EAAE,CACZ,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KACpC,IAAI,CAAC;IACV,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,MAAM,4BAA4B,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,KAAK,EAAE,MAAM;IAClD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"JobQueueWorker.d.ts","sourceRoot":"","sources":["../../src/job/JobQueueWorker.ts"],"names":[],"mappings":"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"}
|
package/dist/node.js
CHANGED
|
@@ -303,6 +303,7 @@ class JobQueueClient {
|
|
|
303
303
|
status: JobStatus2.PENDING
|
|
304
304
|
};
|
|
305
305
|
const id = await this.storage.add(job);
|
|
306
|
+
this.server?.handleJobAdded(id);
|
|
306
307
|
return this.createJobHandle(id);
|
|
307
308
|
}
|
|
308
309
|
async submitBatch(inputs, options) {
|
|
@@ -342,29 +343,52 @@ class JobQueueClient {
|
|
|
342
343
|
async waitFor(jobId) {
|
|
343
344
|
if (!jobId)
|
|
344
345
|
throw new JobNotFoundError("Cannot wait for undefined job");
|
|
346
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
347
|
+
promise.catch(() => {});
|
|
348
|
+
const promises = this.activeJobPromises.get(jobId) || [];
|
|
349
|
+
promises.push({ resolve, reject });
|
|
350
|
+
this.activeJobPromises.set(jobId, promises);
|
|
345
351
|
const job = await this.getJob(jobId);
|
|
346
|
-
if (!job)
|
|
352
|
+
if (!job) {
|
|
353
|
+
this.removePromise(jobId, resolve, reject);
|
|
347
354
|
throw new JobNotFoundError(`Job ${jobId} not found`);
|
|
355
|
+
}
|
|
348
356
|
if (job.status === JobStatus2.COMPLETED) {
|
|
357
|
+
this.removePromise(jobId, resolve, reject);
|
|
349
358
|
return job.output;
|
|
350
359
|
}
|
|
351
360
|
if (job.status === JobStatus2.DISABLED) {
|
|
361
|
+
this.removePromise(jobId, resolve, reject);
|
|
352
362
|
throw new JobDisabledError(`Job ${jobId} was disabled`);
|
|
353
363
|
}
|
|
354
364
|
if (job.status === JobStatus2.FAILED) {
|
|
365
|
+
this.removePromise(jobId, resolve, reject);
|
|
355
366
|
throw this.buildErrorFromJob(job);
|
|
356
367
|
}
|
|
357
|
-
const { promise, resolve, reject } = Promise.withResolvers();
|
|
358
|
-
promise.catch(() => {});
|
|
359
|
-
const promises = this.activeJobPromises.get(jobId) || [];
|
|
360
|
-
promises.push({ resolve, reject });
|
|
361
|
-
this.activeJobPromises.set(jobId, promises);
|
|
362
368
|
return promise;
|
|
363
369
|
}
|
|
370
|
+
removePromise(jobId, resolve, reject) {
|
|
371
|
+
const list = this.activeJobPromises.get(jobId);
|
|
372
|
+
if (!list)
|
|
373
|
+
return;
|
|
374
|
+
const idx = list.findIndex((p) => p.resolve === resolve && p.reject === reject);
|
|
375
|
+
if (idx !== -1)
|
|
376
|
+
list.splice(idx, 1);
|
|
377
|
+
if (list.length === 0)
|
|
378
|
+
this.activeJobPromises.delete(jobId);
|
|
379
|
+
}
|
|
364
380
|
async abort(jobId) {
|
|
365
381
|
if (!jobId)
|
|
366
382
|
throw new JobNotFoundError("Cannot abort undefined job");
|
|
367
|
-
|
|
383
|
+
const firedLocally = this.server?.abortJob(jobId) ?? false;
|
|
384
|
+
if (!firedLocally) {
|
|
385
|
+
try {
|
|
386
|
+
await this.storage.abort(jobId);
|
|
387
|
+
} finally {
|
|
388
|
+
this.events.emit("job_aborting", this.queueName, jobId);
|
|
389
|
+
}
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
368
392
|
this.events.emit("job_aborting", this.queueName, jobId);
|
|
369
393
|
}
|
|
370
394
|
async abortJobRun(jobRunId) {
|
|
@@ -531,7 +555,7 @@ class JobQueueClient {
|
|
|
531
555
|
|
|
532
556
|
// src/job/JobQueueServer.ts
|
|
533
557
|
import { JobStatus as JobStatus4 } from "@workglow/storage";
|
|
534
|
-
import { EventEmitter as EventEmitter3 } from "@workglow/util";
|
|
558
|
+
import { EventEmitter as EventEmitter3, getLogger as getLogger2 } from "@workglow/util";
|
|
535
559
|
|
|
536
560
|
// src/limiter/NullLimiter.ts
|
|
537
561
|
import { createServiceToken } from "@workglow/util";
|
|
@@ -567,10 +591,14 @@ class JobQueueWorker {
|
|
|
567
591
|
jobClass;
|
|
568
592
|
limiter;
|
|
569
593
|
pollIntervalMs;
|
|
594
|
+
stopTimeoutMs;
|
|
570
595
|
events = new EventEmitter2;
|
|
571
596
|
running = false;
|
|
597
|
+
inFlight = new Map;
|
|
572
598
|
wakeResolve = null;
|
|
573
599
|
wakeTimer = null;
|
|
600
|
+
wakePending = false;
|
|
601
|
+
loopPromise = null;
|
|
574
602
|
activeJobAbortControllers = new Map;
|
|
575
603
|
processingTimes = new Map;
|
|
576
604
|
constructor(jobClass, options) {
|
|
@@ -580,6 +608,7 @@ class JobQueueWorker {
|
|
|
580
608
|
this.jobClass = jobClass;
|
|
581
609
|
this.limiter = options.limiter ?? new NullLimiter;
|
|
582
610
|
this.pollIntervalMs = options.pollIntervalMs ?? 100;
|
|
611
|
+
this.stopTimeoutMs = options.stopTimeoutMs ?? 30000;
|
|
583
612
|
}
|
|
584
613
|
async start() {
|
|
585
614
|
if (this.running) {
|
|
@@ -587,17 +616,27 @@ class JobQueueWorker {
|
|
|
587
616
|
}
|
|
588
617
|
this.running = true;
|
|
589
618
|
this.events.emit("worker_start");
|
|
590
|
-
this.processJobs();
|
|
619
|
+
this.loopPromise = this.processJobs();
|
|
591
620
|
return this;
|
|
592
621
|
}
|
|
622
|
+
requestAbort(jobId) {
|
|
623
|
+
const controller = this.activeJobAbortControllers.get(jobId);
|
|
624
|
+
if (controller && !controller.signal.aborted) {
|
|
625
|
+
controller.abort();
|
|
626
|
+
return true;
|
|
627
|
+
}
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
593
630
|
notify() {
|
|
631
|
+
this.wakePending = true;
|
|
594
632
|
if (this.wakeResolve) {
|
|
595
633
|
if (this.wakeTimer) {
|
|
596
634
|
clearTimeout(this.wakeTimer);
|
|
597
635
|
this.wakeTimer = null;
|
|
598
636
|
}
|
|
599
|
-
this.wakeResolve
|
|
637
|
+
const resolve = this.wakeResolve;
|
|
600
638
|
this.wakeResolve = null;
|
|
639
|
+
resolve();
|
|
601
640
|
}
|
|
602
641
|
}
|
|
603
642
|
async stop() {
|
|
@@ -606,15 +645,24 @@ class JobQueueWorker {
|
|
|
606
645
|
}
|
|
607
646
|
this.running = false;
|
|
608
647
|
this.notify();
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
648
|
+
const loopPromise = this.loopPromise;
|
|
649
|
+
this.loopPromise = null;
|
|
650
|
+
if (loopPromise) {
|
|
651
|
+
await loopPromise;
|
|
652
|
+
}
|
|
653
|
+
if (this.stopTimeoutMs > 0 && this.inFlight.size > 0) {
|
|
654
|
+
const drain = Promise.allSettled([...this.inFlight.values()]);
|
|
655
|
+
await Promise.race([drain, sleep(this.stopTimeoutMs)]);
|
|
656
|
+
}
|
|
657
|
+
if (this.inFlight.size > 0) {
|
|
658
|
+
for (const controller of this.activeJobAbortControllers.values()) {
|
|
659
|
+
if (!controller.signal.aborted) {
|
|
660
|
+
controller.abort();
|
|
661
|
+
}
|
|
615
662
|
}
|
|
663
|
+
const abortDrain = Promise.allSettled([...this.inFlight.values()]);
|
|
664
|
+
await Promise.race([abortDrain, sleep(1000)]);
|
|
616
665
|
}
|
|
617
|
-
await sleep(sleepTime);
|
|
618
666
|
this.events.emit("worker_stop");
|
|
619
667
|
return this;
|
|
620
668
|
}
|
|
@@ -662,6 +710,10 @@ class JobQueueWorker {
|
|
|
662
710
|
if (canProceed) {
|
|
663
711
|
const job = await this.next();
|
|
664
712
|
if (job) {
|
|
713
|
+
if (!this.running) {
|
|
714
|
+
await this.releaseClaimedJob(job);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
665
717
|
this.processSingleJob(job);
|
|
666
718
|
continue;
|
|
667
719
|
}
|
|
@@ -690,18 +742,27 @@ class JobQueueWorker {
|
|
|
690
742
|
return this.pollIntervalMs;
|
|
691
743
|
}
|
|
692
744
|
waitForWakeOrTimeout(timeoutMs) {
|
|
745
|
+
if (this.wakePending) {
|
|
746
|
+
this.wakePending = false;
|
|
747
|
+
return Promise.resolve();
|
|
748
|
+
}
|
|
693
749
|
return new Promise((resolve) => {
|
|
694
750
|
this.wakeTimer = setTimeout(() => {
|
|
695
751
|
this.wakeTimer = null;
|
|
696
752
|
this.wakeResolve = null;
|
|
753
|
+
this.wakePending = false;
|
|
697
754
|
resolve();
|
|
698
755
|
}, timeoutMs);
|
|
699
756
|
this.wakeResolve = () => {
|
|
757
|
+
this.wakePending = false;
|
|
700
758
|
resolve();
|
|
701
759
|
};
|
|
702
760
|
});
|
|
703
761
|
}
|
|
704
762
|
async checkForAbortingJobs() {
|
|
763
|
+
if (this.activeJobAbortControllers.size === 0) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
705
766
|
const abortingJobs = await this.storage.peek(JobStatus3.ABORTING);
|
|
706
767
|
for (const jobData of abortingJobs) {
|
|
707
768
|
const controller = this.activeJobAbortControllers.get(jobData.id);
|
|
@@ -714,6 +775,8 @@ class JobQueueWorker {
|
|
|
714
775
|
if (!job || !job.id) {
|
|
715
776
|
throw new JobNotFoundError("Invalid job provided for processing");
|
|
716
777
|
}
|
|
778
|
+
const { promise: inFlightPromise, resolve: resolveInFlight } = Promise.withResolvers();
|
|
779
|
+
this.inFlight.set(job.id, inFlightPromise);
|
|
717
780
|
const startTime = Date.now();
|
|
718
781
|
const telemetry = getTelemetryProvider();
|
|
719
782
|
const span = telemetry.isEnabled ? telemetry.startSpan("workglow.job.process", {
|
|
@@ -764,7 +827,12 @@ class JobQueueWorker {
|
|
|
764
827
|
span?.setAttributes({ "workglow.job.error": spanErrorMessage });
|
|
765
828
|
} finally {
|
|
766
829
|
span?.end();
|
|
767
|
-
|
|
830
|
+
try {
|
|
831
|
+
await this.limiter.recordJobCompletion();
|
|
832
|
+
} finally {
|
|
833
|
+
this.inFlight.delete(job.id);
|
|
834
|
+
resolveInFlight();
|
|
835
|
+
}
|
|
768
836
|
}
|
|
769
837
|
}
|
|
770
838
|
async executeJob(job, signal) {
|
|
@@ -777,7 +845,6 @@ class JobQueueWorker {
|
|
|
777
845
|
}
|
|
778
846
|
async updateProgress(jobId, progress, message = "", details = null) {
|
|
779
847
|
progress = Math.max(0, Math.min(100, progress));
|
|
780
|
-
await this.storage.saveProgress(jobId, progress, message, details);
|
|
781
848
|
this.events.emit("job_progress", jobId, progress, message, details);
|
|
782
849
|
}
|
|
783
850
|
async completeJob(job, output) {
|
|
@@ -830,6 +897,13 @@ class JobQueueWorker {
|
|
|
830
897
|
this.cleanupJob(job.id);
|
|
831
898
|
}
|
|
832
899
|
}
|
|
900
|
+
async releaseClaimedJob(job) {
|
|
901
|
+
try {
|
|
902
|
+
await this.storage.release(job.id);
|
|
903
|
+
} catch (err) {
|
|
904
|
+
getLogger().error("releaseClaimedJob errored:", { error: err });
|
|
905
|
+
}
|
|
906
|
+
}
|
|
833
907
|
async rescheduleJob(job, retryDate) {
|
|
834
908
|
try {
|
|
835
909
|
job.status = JobStatus3.PENDING;
|
|
@@ -848,6 +922,9 @@ class JobQueueWorker {
|
|
|
848
922
|
createAbortController(jobId) {
|
|
849
923
|
if (!jobId)
|
|
850
924
|
throw new JobNotFoundError("Cannot create abort controller for undefined job");
|
|
925
|
+
if (!this.inFlight.has(jobId)) {
|
|
926
|
+
throw new Error(`createAbortController invariant violated: jobId ${String(jobId)} is not in inFlight. ` + `Abort controllers must only be created from within processSingleJob.`);
|
|
927
|
+
}
|
|
851
928
|
if (this.activeJobAbortControllers.has(jobId)) {
|
|
852
929
|
return this.activeJobAbortControllers.get(jobId);
|
|
853
930
|
}
|
|
@@ -857,13 +934,18 @@ class JobQueueWorker {
|
|
|
857
934
|
return abortController;
|
|
858
935
|
}
|
|
859
936
|
async handleAbort(jobId) {
|
|
937
|
+
if (this.inFlight.has(jobId)) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
860
940
|
const job = await this.getJob(jobId);
|
|
861
941
|
if (!job) {
|
|
862
942
|
getLogger().error("handleAbort: job not found", { jobId });
|
|
863
943
|
return;
|
|
864
944
|
}
|
|
865
|
-
|
|
866
|
-
|
|
945
|
+
if (job.status === JobStatus3.COMPLETED || job.status === JobStatus3.FAILED || job.status === JobStatus3.DISABLED) {
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
await this.failJob(job, new AbortSignalJobError("Job Aborted"));
|
|
867
949
|
}
|
|
868
950
|
async getJob(id) {
|
|
869
951
|
const job = await this.storage.get(id);
|
|
@@ -920,6 +1002,7 @@ class JobQueueServer {
|
|
|
920
1002
|
deleteAfterFailureMs;
|
|
921
1003
|
deleteAfterDisabledMs;
|
|
922
1004
|
cleanupIntervalMs;
|
|
1005
|
+
stopTimeoutMs;
|
|
923
1006
|
events = new EventEmitter3;
|
|
924
1007
|
workers = [];
|
|
925
1008
|
clients = new Set;
|
|
@@ -946,6 +1029,7 @@ class JobQueueServer {
|
|
|
946
1029
|
this.deleteAfterFailureMs = options.deleteAfterFailureMs;
|
|
947
1030
|
this.deleteAfterDisabledMs = options.deleteAfterDisabledMs;
|
|
948
1031
|
this.cleanupIntervalMs = options.cleanupIntervalMs ?? 1e4;
|
|
1032
|
+
this.stopTimeoutMs = options.stopTimeoutMs;
|
|
949
1033
|
this.initializeWorkers();
|
|
950
1034
|
}
|
|
951
1035
|
async start() {
|
|
@@ -961,11 +1045,21 @@ class JobQueueServer {
|
|
|
961
1045
|
this.notifyWorkers();
|
|
962
1046
|
}
|
|
963
1047
|
});
|
|
964
|
-
} catch {
|
|
1048
|
+
} catch (err) {
|
|
1049
|
+
getLogger2().debug("subscribeToChanges unsupported on this storage", {
|
|
1050
|
+
queueName: this.queueName,
|
|
1051
|
+
error: err
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
965
1054
|
await Promise.all(this.workers.map((worker) => worker.start()));
|
|
966
|
-
this.
|
|
1055
|
+
if (this.hasRetentionTtls()) {
|
|
1056
|
+
this.startCleanupLoop();
|
|
1057
|
+
}
|
|
967
1058
|
return this;
|
|
968
1059
|
}
|
|
1060
|
+
hasRetentionTtls() {
|
|
1061
|
+
return this.deleteAfterCompletionMs !== undefined && this.deleteAfterCompletionMs > 0 || this.deleteAfterFailureMs !== undefined && this.deleteAfterFailureMs > 0 || this.deleteAfterDisabledMs !== undefined && this.deleteAfterDisabledMs > 0;
|
|
1062
|
+
}
|
|
969
1063
|
async stop() {
|
|
970
1064
|
if (!this.running) {
|
|
971
1065
|
return this;
|
|
@@ -1024,6 +1118,17 @@ class JobQueueServer {
|
|
|
1024
1118
|
worker.notify();
|
|
1025
1119
|
}
|
|
1026
1120
|
}
|
|
1121
|
+
handleJobAdded(_jobId) {
|
|
1122
|
+
this.notifyWorkers();
|
|
1123
|
+
}
|
|
1124
|
+
abortJob(jobId) {
|
|
1125
|
+
for (const worker of this.workers) {
|
|
1126
|
+
if (worker.requestAbort(jobId)) {
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
return false;
|
|
1131
|
+
}
|
|
1027
1132
|
on(event, listener) {
|
|
1028
1133
|
this.events.on(event, listener);
|
|
1029
1134
|
}
|
|
@@ -1041,7 +1146,8 @@ class JobQueueServer {
|
|
|
1041
1146
|
storage: this.storage,
|
|
1042
1147
|
queueName: this.queueName,
|
|
1043
1148
|
limiter: this.limiter,
|
|
1044
|
-
pollIntervalMs: this.pollIntervalMs
|
|
1149
|
+
pollIntervalMs: this.pollIntervalMs,
|
|
1150
|
+
stopTimeoutMs: this.stopTimeoutMs
|
|
1045
1151
|
});
|
|
1046
1152
|
worker.on("job_start", (jobId) => {
|
|
1047
1153
|
this.stats = { ...this.stats, totalJobs: this.stats.totalJobs + 1 };
|
|
@@ -1490,4 +1596,4 @@ export {
|
|
|
1490
1596
|
AbortSignalJobError
|
|
1491
1597
|
};
|
|
1492
1598
|
|
|
1493
|
-
//# debugId=
|
|
1599
|
+
//# debugId=399A3F0D883F203464756E2164756E21
|