bullmq 5.63.1 → 5.64.0
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/cjs/classes/lock-manager.js +165 -0
- package/dist/cjs/classes/lock-manager.js.map +1 -0
- package/dist/cjs/classes/queue-events.js +16 -2
- package/dist/cjs/classes/queue-events.js.map +1 -1
- package/dist/cjs/classes/worker.js +60 -69
- package/dist/cjs/classes/worker.js.map +1 -1
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/index.js +3 -2
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/classes/lock-manager.d.ts +91 -0
- package/dist/esm/classes/lock-manager.js +161 -0
- package/dist/esm/classes/lock-manager.js.map +1 -0
- package/dist/esm/classes/queue-events.d.ts +1 -0
- package/dist/esm/classes/queue-events.js +16 -2
- package/dist/esm/classes/queue-events.js.map +1 -1
- package/dist/esm/classes/worker.d.ts +42 -22
- package/dist/esm/classes/worker.js +60 -69
- package/dist/esm/classes/worker.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/types/processor.d.ts +1 -1
- package/dist/esm/utils/index.js +3 -2
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +18 -48
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { AbortController } from 'node-abort-controller';
|
|
2
|
+
import { Span } from '../interfaces';
|
|
3
|
+
export interface LockManagerOptions {
|
|
4
|
+
lockRenewTime: number;
|
|
5
|
+
lockDuration: number;
|
|
6
|
+
workerId: string;
|
|
7
|
+
workerName?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Minimal interface that LockManager needs from Worker.
|
|
11
|
+
* This allows LockManager to access worker methods without inheriting from QueueBase.
|
|
12
|
+
*/
|
|
13
|
+
export interface LockManagerWorkerContext {
|
|
14
|
+
/**
|
|
15
|
+
* Extends locks for multiple jobs.
|
|
16
|
+
*/
|
|
17
|
+
extendJobLocks(jobIds: string[], tokens: string[], duration: number): Promise<string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Emits events to worker listeners.
|
|
20
|
+
*/
|
|
21
|
+
emit(event: string | symbol, ...args: any[]): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Wraps code with telemetry tracing.
|
|
24
|
+
*/
|
|
25
|
+
trace<T>(spanKind: any, operation: string, destination: string, callback: (span?: Span) => Promise<T> | T): Promise<T> | T;
|
|
26
|
+
/**
|
|
27
|
+
* Queue name for telemetry.
|
|
28
|
+
*/
|
|
29
|
+
name: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Manages lock renewal for BullMQ workers.
|
|
33
|
+
* It periodically extends locks for active jobs to prevent them from being
|
|
34
|
+
* considered stalled by other workers.
|
|
35
|
+
*/
|
|
36
|
+
export declare class LockManager {
|
|
37
|
+
private worker;
|
|
38
|
+
private opts;
|
|
39
|
+
protected lockRenewalTimer?: NodeJS.Timeout;
|
|
40
|
+
protected trackedJobs: Map<string, {
|
|
41
|
+
token: string;
|
|
42
|
+
ts: number;
|
|
43
|
+
abortController?: AbortController;
|
|
44
|
+
}>;
|
|
45
|
+
protected closed: boolean;
|
|
46
|
+
constructor(worker: LockManagerWorkerContext, opts: LockManagerOptions);
|
|
47
|
+
/**
|
|
48
|
+
* Starts the lock manager timers for lock renewal.
|
|
49
|
+
*/
|
|
50
|
+
start(): void;
|
|
51
|
+
protected extendLocks(jobIds: string[]): Promise<void>;
|
|
52
|
+
private startLockExtenderTimer;
|
|
53
|
+
/**
|
|
54
|
+
* Stops the lock manager and clears all timers.
|
|
55
|
+
*/
|
|
56
|
+
close(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Adds a job to be tracked for lock renewal.
|
|
59
|
+
* Returns an AbortController if shouldCreateController is true, undefined otherwise.
|
|
60
|
+
*/
|
|
61
|
+
trackJob(jobId: string, token: string, ts: number, shouldCreateController: boolean): AbortController | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Removes a job from lock renewal tracking.
|
|
64
|
+
*/
|
|
65
|
+
untrackJob(jobId: string): void;
|
|
66
|
+
/**
|
|
67
|
+
* Gets the number of jobs currently being tracked.
|
|
68
|
+
*/
|
|
69
|
+
getActiveJobCount(): number;
|
|
70
|
+
/**
|
|
71
|
+
* Checks if the lock manager is running.
|
|
72
|
+
*/
|
|
73
|
+
isRunning(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Cancels a specific job by aborting its signal.
|
|
76
|
+
* @param jobId - The ID of the job to cancel
|
|
77
|
+
* @param reason - Optional reason for the cancellation
|
|
78
|
+
* @returns true if the job was found and cancelled, false otherwise
|
|
79
|
+
*/
|
|
80
|
+
cancelJob(jobId: string, reason?: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Cancels all tracked jobs by aborting their signals.
|
|
83
|
+
* @param reason - Optional reason for the cancellation
|
|
84
|
+
*/
|
|
85
|
+
cancelAllJobs(reason?: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Gets a list of all tracked job IDs.
|
|
88
|
+
* @returns Array of job IDs currently being tracked
|
|
89
|
+
*/
|
|
90
|
+
getTrackedJobIds(): string[];
|
|
91
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { AbortController } from 'node-abort-controller';
|
|
2
|
+
import { SpanKind, TelemetryAttributes } from '../enums';
|
|
3
|
+
/**
|
|
4
|
+
* Manages lock renewal for BullMQ workers.
|
|
5
|
+
* It periodically extends locks for active jobs to prevent them from being
|
|
6
|
+
* considered stalled by other workers.
|
|
7
|
+
*/
|
|
8
|
+
export class LockManager {
|
|
9
|
+
constructor(worker, opts) {
|
|
10
|
+
this.worker = worker;
|
|
11
|
+
this.opts = opts;
|
|
12
|
+
// Maps job ids with their tokens, timestamps, and abort controllers
|
|
13
|
+
this.trackedJobs = new Map();
|
|
14
|
+
this.closed = false;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Starts the lock manager timers for lock renewal.
|
|
18
|
+
*/
|
|
19
|
+
start() {
|
|
20
|
+
if (this.closed) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Start lock renewal timer if not disabled
|
|
24
|
+
if (this.opts.lockRenewTime > 0) {
|
|
25
|
+
this.startLockExtenderTimer();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async extendLocks(jobIds) {
|
|
29
|
+
await this.worker.trace(SpanKind.INTERNAL, 'extendLocks', this.worker.name, async (span) => {
|
|
30
|
+
span === null || span === void 0 ? void 0 : span.setAttributes({
|
|
31
|
+
[TelemetryAttributes.WorkerId]: this.opts.workerId,
|
|
32
|
+
[TelemetryAttributes.WorkerName]: this.opts.workerName,
|
|
33
|
+
[TelemetryAttributes.WorkerJobsToExtendLocks]: jobIds,
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
const jobTokens = jobIds.map(id => { var _a; return ((_a = this.trackedJobs.get(id)) === null || _a === void 0 ? void 0 : _a.token) || ''; });
|
|
37
|
+
const erroredJobIds = await this.worker.extendJobLocks(jobIds, jobTokens, this.opts.lockDuration);
|
|
38
|
+
if (erroredJobIds.length > 0) {
|
|
39
|
+
this.worker.emit('lockRenewalFailed', erroredJobIds);
|
|
40
|
+
for (const jobId of erroredJobIds) {
|
|
41
|
+
this.worker.emit('error', new Error(`could not renew lock for job ${jobId}`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const succeededJobIds = jobIds.filter(id => !erroredJobIds.includes(id));
|
|
45
|
+
if (succeededJobIds.length > 0) {
|
|
46
|
+
this.worker.emit('locksRenewed', {
|
|
47
|
+
count: succeededJobIds.length,
|
|
48
|
+
jobIds: succeededJobIds,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
this.worker.emit('error', err);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
startLockExtenderTimer() {
|
|
58
|
+
clearTimeout(this.lockRenewalTimer);
|
|
59
|
+
if (!this.closed) {
|
|
60
|
+
this.lockRenewalTimer = setTimeout(async () => {
|
|
61
|
+
// Get all the jobs whose locks expire in less than 1/2 of the lockRenewTime
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const jobsToExtend = [];
|
|
64
|
+
for (const jobId of this.trackedJobs.keys()) {
|
|
65
|
+
const tracked = this.trackedJobs.get(jobId);
|
|
66
|
+
const { ts, token, abortController } = tracked;
|
|
67
|
+
if (!ts) {
|
|
68
|
+
this.trackedJobs.set(jobId, { token, ts: now, abortController });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (ts + this.opts.lockRenewTime / 2 < now) {
|
|
72
|
+
this.trackedJobs.set(jobId, { token, ts: now, abortController });
|
|
73
|
+
jobsToExtend.push(jobId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (jobsToExtend.length) {
|
|
77
|
+
await this.extendLocks(jobsToExtend);
|
|
78
|
+
}
|
|
79
|
+
this.startLockExtenderTimer();
|
|
80
|
+
}, this.opts.lockRenewTime / 2);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Stops the lock manager and clears all timers.
|
|
85
|
+
*/
|
|
86
|
+
async close() {
|
|
87
|
+
if (this.closed) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.closed = true;
|
|
91
|
+
if (this.lockRenewalTimer) {
|
|
92
|
+
clearTimeout(this.lockRenewalTimer);
|
|
93
|
+
this.lockRenewalTimer = undefined;
|
|
94
|
+
}
|
|
95
|
+
this.trackedJobs.clear();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Adds a job to be tracked for lock renewal.
|
|
99
|
+
* Returns an AbortController if shouldCreateController is true, undefined otherwise.
|
|
100
|
+
*/
|
|
101
|
+
trackJob(jobId, token, ts, shouldCreateController) {
|
|
102
|
+
const abortController = shouldCreateController
|
|
103
|
+
? new AbortController()
|
|
104
|
+
: undefined;
|
|
105
|
+
if (!this.closed && jobId) {
|
|
106
|
+
this.trackedJobs.set(jobId, { token, ts, abortController });
|
|
107
|
+
}
|
|
108
|
+
return abortController;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Removes a job from lock renewal tracking.
|
|
112
|
+
*/
|
|
113
|
+
untrackJob(jobId) {
|
|
114
|
+
this.trackedJobs.delete(jobId);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Gets the number of jobs currently being tracked.
|
|
118
|
+
*/
|
|
119
|
+
getActiveJobCount() {
|
|
120
|
+
return this.trackedJobs.size;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Checks if the lock manager is running.
|
|
124
|
+
*/
|
|
125
|
+
isRunning() {
|
|
126
|
+
return !this.closed && this.lockRenewalTimer !== undefined;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Cancels a specific job by aborting its signal.
|
|
130
|
+
* @param jobId - The ID of the job to cancel
|
|
131
|
+
* @param reason - Optional reason for the cancellation
|
|
132
|
+
* @returns true if the job was found and cancelled, false otherwise
|
|
133
|
+
*/
|
|
134
|
+
cancelJob(jobId, reason) {
|
|
135
|
+
const tracked = this.trackedJobs.get(jobId);
|
|
136
|
+
if (tracked === null || tracked === void 0 ? void 0 : tracked.abortController) {
|
|
137
|
+
tracked.abortController.abort(reason);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Cancels all tracked jobs by aborting their signals.
|
|
144
|
+
* @param reason - Optional reason for the cancellation
|
|
145
|
+
*/
|
|
146
|
+
cancelAllJobs(reason) {
|
|
147
|
+
for (const tracked of this.trackedJobs.values()) {
|
|
148
|
+
if (tracked.abortController) {
|
|
149
|
+
tracked.abortController.abort(reason);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Gets a list of all tracked job IDs.
|
|
155
|
+
* @returns Array of job IDs currently being tracked
|
|
156
|
+
*/
|
|
157
|
+
getTrackedJobIds() {
|
|
158
|
+
return Array.from(this.trackedJobs.keys());
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=lock-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-manager.js","sourceRoot":"","sources":["../../../src/classes/lock-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AA6CzD;;;;GAIG;AACH,MAAM,OAAO,WAAW;IAUtB,YACU,MAAgC,EAChC,IAAwB;QADxB,WAAM,GAAN,MAAM,CAA0B;QAChC,SAAI,GAAJ,IAAI,CAAoB;QATlC,oEAAoE;QAC1D,gBAAW,GAAG,IAAI,GAAG,EAG5B,CAAC;QACM,WAAM,GAAG,KAAK,CAAC;IAKtB,CAAC;IAEJ;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,2CAA2C;QAC3C,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAES,KAAK,CAAC,WAAW,CAAC,MAAgB;QAC1C,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CACrB,QAAQ,CAAC,QAAQ,EACjB,aAAa,EACb,IAAI,CAAC,MAAM,CAAC,IAAI,EAChB,KAAK,EAAE,IAAW,EAAE,EAAE;YACpB,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,CAAC;gBAClB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAClD,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;gBACtD,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,EAAE,MAAM;aACtD,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAC1B,EAAE,CAAC,EAAE,WAAC,OAAA,CAAA,MAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,0CAAE,KAAK,KAAI,EAAE,CAAA,EAAA,CAC5C,CAAC;gBAEF,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CACpD,MAAM,EACN,SAAS,EACT,IAAI,CAAC,IAAI,CAAC,YAAY,CACvB,CAAC;gBAEF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;oBAErD,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;wBAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,OAAO,EACP,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CACnD,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CACnC,EAAE,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAClC,CAAC;gBAEF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;wBAC/B,KAAK,EAAE,eAAe,CAAC,MAAM;wBAC7B,MAAM,EAAE,eAAe;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAY,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAEO,sBAAsB;QAC5B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEpC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;gBAC5C,4EAA4E;gBAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,MAAM,YAAY,GAAa,EAAE,CAAC;gBAElC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;oBAC7C,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;oBAC/C,IAAI,CAAC,EAAE,EAAE,CAAC;wBACR,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC;wBACjE,SAAS;oBACX,CAAC;oBAED,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;wBAC3C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,CAAC;wBACjE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;gBAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;oBACxB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;gBACvC,CAAC;gBAED,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,QAAQ,CACN,KAAa,EACb,KAAa,EACb,EAAU,EACV,sBAA+B;QAE/B,MAAM,eAAe,GAAG,sBAAsB;YAC5C,CAAC,CAAC,IAAI,eAAe,EAAE;YACvB,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,KAAa;QACtB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,KAAa,EAAE,MAAe;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,EAAE,CAAC;YAC7B,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,MAAe;QAC3B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC5B,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -269,6 +269,7 @@ type KeyOf<T extends object> = Extract<keyof T, string>;
|
|
|
269
269
|
*/
|
|
270
270
|
export declare class QueueEvents extends QueueBase {
|
|
271
271
|
private running;
|
|
272
|
+
private blocking;
|
|
272
273
|
constructor(name: string, { connection, autorun, ...opts }?: QueueEventsOptions, Connection?: typeof RedisConnection);
|
|
273
274
|
emit<QEL extends QueueEventsListener = QueueEventsListener, U extends KeyOf<QEL> = KeyOf<QEL>>(event: U, ...args: CustomParameters<QEL[U]>): boolean;
|
|
274
275
|
off<QEL extends QueueEventsListener = QueueEventsListener, U extends KeyOf<QEL> = KeyOf<QEL>>(eventName: U, listener: QEL[U]): this;
|
|
@@ -17,6 +17,7 @@ export class QueueEvents extends QueueBase {
|
|
|
17
17
|
? connection.duplicate()
|
|
18
18
|
: connection }), Connection, true);
|
|
19
19
|
this.running = false;
|
|
20
|
+
this.blocking = false;
|
|
20
21
|
this.opts = Object.assign({
|
|
21
22
|
blockingTimeout: 10000,
|
|
22
23
|
}, this.opts);
|
|
@@ -73,8 +74,10 @@ export class QueueEvents extends QueueBase {
|
|
|
73
74
|
const key = this.keys.events;
|
|
74
75
|
let id = opts.lastEventId || '$';
|
|
75
76
|
while (!this.closing) {
|
|
77
|
+
this.blocking = true;
|
|
76
78
|
// Cast to actual return type, see: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/44301
|
|
77
79
|
const data = await this.checkConnectionError(() => client.xread('BLOCK', opts.blockingTimeout, 'STREAMS', key, id));
|
|
80
|
+
this.blocking = false;
|
|
78
81
|
if (data) {
|
|
79
82
|
const stream = data[0];
|
|
80
83
|
const events = stream[1];
|
|
@@ -111,9 +114,20 @@ export class QueueEvents extends QueueBase {
|
|
|
111
114
|
*
|
|
112
115
|
* @returns
|
|
113
116
|
*/
|
|
114
|
-
close() {
|
|
117
|
+
async close() {
|
|
115
118
|
if (!this.closing) {
|
|
116
|
-
this.closing =
|
|
119
|
+
this.closing = (async () => {
|
|
120
|
+
try {
|
|
121
|
+
// As the connection has been wrongly markes as "shared" by QueueBase,
|
|
122
|
+
// we need to forcibly close it here. We should fix QueueBase to avoid this in the future.
|
|
123
|
+
const client = await this.client;
|
|
124
|
+
client.disconnect();
|
|
125
|
+
await this.connection.close(this.blocking);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
this.closed = true;
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
117
131
|
}
|
|
118
132
|
return this.closing;
|
|
119
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-events.js","sourceRoot":"","sources":["../../../src/classes/queue-events.ts"],"names":[],"mappings":";AAOA,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA8PzC;;;;;;GAMG;AACH,MAAM,OAAO,WAAY,SAAQ,SAAS;
|
|
1
|
+
{"version":3,"file":"queue-events.js","sourceRoot":"","sources":["../../../src/classes/queue-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,6 +89,21 @@ export interface WorkerListener<DataType = any, ResultType = any, NameType exten
|
|
|
89
89
|
* has been moved back to the wait list.
|
|
90
90
|
*/
|
|
91
91
|
stalled: (jobId: string, prev: string) => void;
|
|
92
|
+
/**
|
|
93
|
+
* Listen to 'lockRenewalFailed' event.
|
|
94
|
+
*
|
|
95
|
+
* This event is triggered when lock renewal fails for one or more jobs.
|
|
96
|
+
*/
|
|
97
|
+
lockRenewalFailed: (jobIds: string[]) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Listen to 'locksRenewed' event.
|
|
100
|
+
*
|
|
101
|
+
* This event is triggered when locks are successfully renewed.
|
|
102
|
+
*/
|
|
103
|
+
locksRenewed: (data: {
|
|
104
|
+
count: number;
|
|
105
|
+
jobIds: string[];
|
|
106
|
+
}) => void;
|
|
92
107
|
}
|
|
93
108
|
/**
|
|
94
109
|
*
|
|
@@ -106,8 +121,9 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
106
121
|
private _concurrency;
|
|
107
122
|
private childPool;
|
|
108
123
|
private drained;
|
|
109
|
-
private extendLocksTimer;
|
|
110
124
|
private limitUntil;
|
|
125
|
+
private lockManager;
|
|
126
|
+
private processorAcceptsSignal;
|
|
111
127
|
private stalledCheckStopper?;
|
|
112
128
|
private waiting;
|
|
113
129
|
private _repeat;
|
|
@@ -118,11 +134,16 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
118
134
|
protected mainLoopRunning: Promise<void> | null;
|
|
119
135
|
static RateLimitError(): Error;
|
|
120
136
|
constructor(name: string, processor?: string | URL | null | Processor<DataType, ResultType, NameType>, opts?: WorkerOptions, Connection?: typeof RedisConnection);
|
|
137
|
+
/**
|
|
138
|
+
* Public accessor method for LockManager to extend locks.
|
|
139
|
+
* This delegates to the protected scripts object.
|
|
140
|
+
*/
|
|
141
|
+
extendJobLocks(jobIds: string[], tokens: string[], duration: number): Promise<string[]>;
|
|
121
142
|
emit<U extends keyof WorkerListener<DataType, ResultType, NameType>>(event: U, ...args: Parameters<WorkerListener<DataType, ResultType, NameType>[U]>): boolean;
|
|
122
143
|
off<U extends keyof WorkerListener<DataType, ResultType, NameType>>(eventName: U, listener: WorkerListener<DataType, ResultType, NameType>[U]): this;
|
|
123
144
|
on<U extends keyof WorkerListener<DataType, ResultType, NameType>>(event: U, listener: WorkerListener<DataType, ResultType, NameType>[U]): this;
|
|
124
145
|
once<U extends keyof WorkerListener<DataType, ResultType, NameType>>(event: U, listener: WorkerListener<DataType, ResultType, NameType>[U]): this;
|
|
125
|
-
protected callProcessJob(job: Job<DataType, ResultType, NameType>, token: string): Promise<ResultType>;
|
|
146
|
+
protected callProcessJob(job: Job<DataType, ResultType, NameType>, token: string, signal?: AbortSignal): Promise<ResultType>;
|
|
126
147
|
protected createJob(data: JobJsonRaw, jobId: string): Job<DataType, ResultType, NameType>;
|
|
127
148
|
/**
|
|
128
149
|
*
|
|
@@ -131,6 +152,22 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
131
152
|
*
|
|
132
153
|
*/
|
|
133
154
|
waitUntilReady(): Promise<RedisClient>;
|
|
155
|
+
/**
|
|
156
|
+
* Cancels a specific job currently being processed by this worker.
|
|
157
|
+
* The job's processor function will receive an abort signal.
|
|
158
|
+
*
|
|
159
|
+
* @param jobId - The ID of the job to cancel
|
|
160
|
+
* @param reason - Optional reason for the cancellation
|
|
161
|
+
* @returns true if the job was found and cancelled, false otherwise
|
|
162
|
+
*/
|
|
163
|
+
cancelJob(jobId: string, reason?: string): boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Cancels all jobs currently being processed by this worker.
|
|
166
|
+
* All active job processor functions will receive abort signals.
|
|
167
|
+
*
|
|
168
|
+
* @param reason - Optional reason for the cancellation
|
|
169
|
+
*/
|
|
170
|
+
cancelAllJobs(reason?: string): void;
|
|
134
171
|
set concurrency(concurrency: number);
|
|
135
172
|
get concurrency(): number;
|
|
136
173
|
get repeat(): Promise<Repeat>;
|
|
@@ -169,25 +206,10 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
169
206
|
delay(milliseconds?: number, abortController?: AbortController): Promise<void>;
|
|
170
207
|
private updateDelays;
|
|
171
208
|
protected nextJobFromJobData(jobData?: JobJsonRaw, jobId?: string, token?: string): Promise<Job<DataType, ResultType, NameType>>;
|
|
172
|
-
processJob(job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback
|
|
173
|
-
job: Job;
|
|
174
|
-
ts: number;
|
|
175
|
-
}>): Promise<void | Job<DataType, ResultType, NameType>>;
|
|
209
|
+
processJob(job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback?: () => boolean): Promise<void | Job<DataType, ResultType, NameType>>;
|
|
176
210
|
private getUnrecoverableErrorMessage;
|
|
177
|
-
protected handleCompleted(result: ResultType, job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback
|
|
178
|
-
|
|
179
|
-
ts: number;
|
|
180
|
-
}>, inProgressItem: {
|
|
181
|
-
job: Job;
|
|
182
|
-
ts: number;
|
|
183
|
-
}, span?: Span): Promise<Job<DataType, ResultType, NameType>>;
|
|
184
|
-
protected handleFailed(err: Error, job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback: () => boolean, jobsInProgress: Set<{
|
|
185
|
-
job: Job;
|
|
186
|
-
ts: number;
|
|
187
|
-
}>, inProgressItem: {
|
|
188
|
-
job: Job;
|
|
189
|
-
ts: number;
|
|
190
|
-
}, span?: Span): Promise<Job<DataType, ResultType, NameType>>;
|
|
211
|
+
protected handleCompleted(result: ResultType, job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback?: () => boolean, span?: Span): Promise<Job<DataType, ResultType, NameType>>;
|
|
212
|
+
protected handleFailed(err: Error, job: Job<DataType, ResultType, NameType>, token: string, fetchNextCallback?: () => boolean, span?: Span): Promise<Job<DataType, ResultType, NameType>>;
|
|
191
213
|
/**
|
|
192
214
|
*
|
|
193
215
|
* Pauses the processing of this queue only for this worker.
|
|
@@ -239,7 +261,6 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
239
261
|
*/
|
|
240
262
|
startStalledCheckTimer(): Promise<void>;
|
|
241
263
|
private stalledChecker;
|
|
242
|
-
private startLockExtenderTimer;
|
|
243
264
|
/**
|
|
244
265
|
* Returns a promise that resolves when active jobs are cleared
|
|
245
266
|
*
|
|
@@ -247,7 +268,6 @@ export declare class Worker<DataType = any, ResultType = any, NameType extends s
|
|
|
247
268
|
*/
|
|
248
269
|
private whenCurrentJobsFinished;
|
|
249
270
|
private retryIfFailed;
|
|
250
|
-
protected extendLocks(jobs: Job[]): Promise<void>;
|
|
251
271
|
private moveStalledJobsToWait;
|
|
252
272
|
private moveLimitedBackToWait;
|
|
253
273
|
}
|