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.
@@ -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":"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"}
@@ -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 = this.disconnect();
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":"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"}
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: () => boolean, jobsInProgress: Set<{
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: () => boolean, jobsInProgress: Set<{
178
- job: Job;
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
  }