@bymax-one/nest-queue 1.2.14 → 1.2.16
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/CHANGELOG.md +50 -1
- package/README.md +77 -68
- package/dist/server/index.cjs +219 -107
- package/dist/server/index.d.cts +57 -23
- package/dist/server/index.d.ts +57 -23
- package/dist/server/index.mjs +219 -107
- package/package.json +1 -1
package/dist/server/index.d.cts
CHANGED
|
@@ -105,9 +105,11 @@ interface BymaxQueueModuleOptions {
|
|
|
105
105
|
*/
|
|
106
106
|
commandTimeoutMs?: number;
|
|
107
107
|
/**
|
|
108
|
-
* The deadline, in milliseconds, for one `
|
|
109
|
-
*
|
|
110
|
-
*
|
|
108
|
+
* The deadline, in milliseconds, for one `QueueService` call that reaches Redis (`enqueue`,
|
|
109
|
+
* `getJob`, `getMetrics`, the scheduler, pause and clean calls, and the rest) in either connection
|
|
110
|
+
* mode, including the wait for the client to be ready on a queue's first call. When it passes, the
|
|
111
|
+
* call rejects with `CONNECTION_TIMEOUT`; an `enqueue` may still complete in Redis afterwards, so
|
|
112
|
+
* retry with a stable `jobId` or `deduplication`. Default: 10_000.
|
|
111
113
|
*/
|
|
112
114
|
enqueueTimeoutMs?: number;
|
|
113
115
|
}
|
|
@@ -401,6 +403,14 @@ declare class ConnectionResolver {
|
|
|
401
403
|
getMode(): QueueConnectionMode;
|
|
402
404
|
/** Whether the library owns (and must close) the connection. */
|
|
403
405
|
isOwned(): boolean;
|
|
406
|
+
/**
|
|
407
|
+
* Settle when the client can take a command. While it is still connecting or reconnecting, every
|
|
408
|
+
* caller shares one wait on its `ready` event, so a health check that polls through a long outage
|
|
409
|
+
* adds one listener set to the client, not one per call, and gives it back when Redis returns. A
|
|
410
|
+
* lazy client (`wait`) connects on its first command and a finished one (`end`) never becomes
|
|
411
|
+
* ready, so both are left for the call itself.
|
|
412
|
+
*/
|
|
413
|
+
awaitReady(): Promise<void>;
|
|
404
414
|
/** Close the library-owned connection on shutdown; never touch a BYO client. */
|
|
405
415
|
teardown(): Promise<void>;
|
|
406
416
|
/** Validate and adopt a bring-your-own client for the Queue role. */
|
|
@@ -446,20 +456,27 @@ declare class QueueService {
|
|
|
446
456
|
* @param overrides - Optional per-queue option overrides.
|
|
447
457
|
*/
|
|
448
458
|
getOrCreateQueue<TData = unknown, TResult = unknown>(queueName: string, overrides?: Partial<Omit<QueueOptions, 'connection' | 'prefix'>>): Queue<TData, TResult>;
|
|
449
|
-
/** The error a producer call receives when Redis does not answer within `enqueueTimeoutMs`. */
|
|
450
|
-
private enqueueTimeout;
|
|
451
459
|
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
460
|
+
* Run one Redis call under the per-call deadline (`enqueueTimeoutMs`), reporting every way Redis
|
|
461
|
+
* can fail to answer as the documented `CONNECTION_TIMEOUT`: the deadline passing, an ioredis
|
|
462
|
+
* command timeout, or a call refused because the connection is down.
|
|
463
|
+
*
|
|
464
|
+
* The first call on a queue name waits for the client to be ready through ONE wait shared by all
|
|
465
|
+
* callers, instead of letting BullMQ start its own unbounded wait per call, so a caller that
|
|
466
|
+
* polls through an outage does not pile up listeners. The call runs only if it is still within
|
|
467
|
+
* its deadline when the client is ready; a caller that was told it timed out never has its call
|
|
468
|
+
* run later, which would turn its retry into a duplicate.
|
|
454
469
|
*/
|
|
455
470
|
private call;
|
|
471
|
+
/** Settle when a call on `queueName` may start: at once for a queue that has been used before. */
|
|
472
|
+
private afterReady;
|
|
456
473
|
/** Resolve the raw cached queue (default generics) for internal delegation. */
|
|
457
474
|
private queueFor;
|
|
458
475
|
/**
|
|
459
476
|
* Add a single job to a queue. The queue is created lazily if needed.
|
|
460
477
|
*
|
|
461
478
|
* Delivery is **at-least-once** — a handler may run more than once for the same
|
|
462
|
-
* job (worker crash, lock expiry, or a shutdown
|
|
479
|
+
* job (worker crash, lock expiry, or a shutdown that outlasts the drain budget). Make handlers
|
|
463
480
|
* idempotent: use an idempotency key on writes, prefer upserts over inserts, or
|
|
464
481
|
* keep an "already-processed" marker keyed by `job.id`.
|
|
465
482
|
*
|
|
@@ -580,9 +597,11 @@ declare class QueueService {
|
|
|
580
597
|
*
|
|
581
598
|
* @param queueName - Target queue.
|
|
582
599
|
* @param start - Page start index (inclusive). Default: 0.
|
|
583
|
-
* @param end - Page end index (inclusive). Default: 50.
|
|
600
|
+
* @param end - Page end index (inclusive). Default: 50. The window may span at most
|
|
601
|
+
* `MAX_JOBS_PAGE_SIZE` (1000) entries, and BullMQ's `-1` (everything) is refused.
|
|
584
602
|
* @param asc - Sort ascending by next run time. Default: true.
|
|
585
603
|
* @returns The registered schedulers in the requested page.
|
|
604
|
+
* @throws {QueueException} `INVALID_OPTIONS` when the window is not a bounded range of integers.
|
|
586
605
|
*/
|
|
587
606
|
getJobSchedulers(queueName: string, start?: number, end?: number, asc?: boolean): Promise<Awaited<ReturnType<Queue['getJobSchedulers']>>>;
|
|
588
607
|
/** Pause a queue, halting the processing of new jobs. */
|
|
@@ -643,7 +662,7 @@ declare class FlowService {
|
|
|
643
662
|
#private;
|
|
644
663
|
private readonly logger;
|
|
645
664
|
private readonly producer?;
|
|
646
|
-
constructor(connection: ConnectionResolver, enabled: boolean, prefix: string, telemetry?: Telemetry);
|
|
665
|
+
constructor(connection: ConnectionResolver, enabled: boolean, prefix: string, telemetry?: Telemetry, enqueueTimeoutMs?: number);
|
|
647
666
|
/**
|
|
648
667
|
* Add a flow tree (a parent with its descendant children). The root job
|
|
649
668
|
* becomes processable only after every descendant has completed.
|
|
@@ -661,7 +680,8 @@ declare class FlowService {
|
|
|
661
680
|
* A job whose custom `jobId` already exists is not added again: its node carries the EXISTING
|
|
662
681
|
* id with the data of this call, so the tree does not describe what is stored; call
|
|
663
682
|
* `QueueService.getJob` when you need it.
|
|
664
|
-
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled
|
|
683
|
+
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled; `CONNECTION_TIMEOUT`
|
|
684
|
+
* when Redis does not answer within `enqueueTimeoutMs` (the flow may still have been added).
|
|
665
685
|
*/
|
|
666
686
|
add(flow: FlowJob): Promise<JobNode>;
|
|
667
687
|
/**
|
|
@@ -670,9 +690,17 @@ declare class FlowService {
|
|
|
670
690
|
* @param flows - Flow tree definitions.
|
|
671
691
|
* @returns The root `JobNode` for each flow, in input order.
|
|
672
692
|
* A job whose custom `jobId` already exists is not added again; see {@link FlowService.add}.
|
|
673
|
-
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled
|
|
693
|
+
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled;
|
|
694
|
+
* `BULK_ENQUEUE_FAILED` for more than 1000 flows; `CONNECTION_TIMEOUT` as for
|
|
695
|
+
* {@link FlowService.add}.
|
|
674
696
|
*/
|
|
675
697
|
addBulk(flows: readonly FlowJob[]): Promise<JobNode[]>;
|
|
698
|
+
/**
|
|
699
|
+
* Hold the caller to `enqueueTimeoutMs`, and report a command timeout or a down connection as
|
|
700
|
+
* `CONNECTION_TIMEOUT`. A call that timed out may still have been added: BullMQ is not asked to
|
|
701
|
+
* cancel it.
|
|
702
|
+
*/
|
|
703
|
+
private bounded;
|
|
676
704
|
/** The command deadline of the producer connection, read when a command has timed out. */
|
|
677
705
|
private commandTimeout;
|
|
678
706
|
/**
|
|
@@ -964,8 +992,9 @@ declare class WorkerRegistry {
|
|
|
964
992
|
private guardDuplicate;
|
|
965
993
|
/**
|
|
966
994
|
* Validate tunable options before constructing a Worker.
|
|
967
|
-
* Enforces `concurrency` in `[1, MAX_WORKER_CONCURRENCY]
|
|
968
|
-
* `limiter.max`/`limiter.duration` `>= 1
|
|
995
|
+
* Enforces whole-number `concurrency` in `[1, MAX_WORKER_CONCURRENCY]`, whole-number
|
|
996
|
+
* `limiter.max`/`limiter.duration` `>= 1`, and `lockDuration`/`stalledInterval` within
|
|
997
|
+
* 1000..2^31 - 1.
|
|
969
998
|
*
|
|
970
999
|
* @param opts - The caller-supplied options (may be undefined).
|
|
971
1000
|
* @throws {QueueException} `WORKER_REGISTRATION_FAILED` when values are out of range.
|
|
@@ -1087,9 +1116,9 @@ declare class QueueEventsRegistry {
|
|
|
1087
1116
|
* HTTP server has stopped, it releases what a request can still be using: the
|
|
1088
1117
|
* flow producer, the cached queues, and finally the Queue-role connection.
|
|
1089
1118
|
*
|
|
1090
|
-
* Delivery is at-least-once: when a worker exceeds the drain budget it is
|
|
1091
|
-
*
|
|
1092
|
-
* worker. Handlers must therefore be idempotent, and `lockDuration` should
|
|
1119
|
+
* Delivery is at-least-once: when a worker exceeds the drain budget it is stopped
|
|
1120
|
+
* without waiting for its job, whose lock then expires so the job becomes `stalled`
|
|
1121
|
+
* and is retried by another worker. Handlers must therefore be idempotent, and `lockDuration` should
|
|
1093
1122
|
* comfortably exceed the worst-case handler runtime so healthy long jobs are
|
|
1094
1123
|
* never treated as stalled.
|
|
1095
1124
|
* @layer server/lifecycle
|
|
@@ -1138,11 +1167,16 @@ declare class QueueLifecycle implements OnModuleDestroy, OnApplicationShutdown {
|
|
|
1138
1167
|
*/
|
|
1139
1168
|
onApplicationShutdown(): Promise<void>;
|
|
1140
1169
|
/**
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1170
|
+
* Stop every worker in parallel, each bounded by what is left of the shutdown budget. A worker
|
|
1171
|
+
* is paused first (it stops fetching and waits for its active jobs) and then closed. One that is
|
|
1172
|
+
* still busy when the budget ends is closed with `close(true)`: because `pause` does not start a
|
|
1173
|
+
* close, that is the worker's FIRST close, so it does not wait for the job and stops the lock
|
|
1174
|
+
* renewal that would otherwise keep running and keep the process alive. The job's lock then
|
|
1175
|
+
* expires, and it stalls and is retried elsewhere. Returns how many workers were stopped
|
|
1176
|
+
* without draining.
|
|
1143
1177
|
*
|
|
1144
1178
|
* @param deadline - The epoch millisecond at which the shutdown budget ends.
|
|
1145
|
-
* @returns The count of
|
|
1179
|
+
* @returns The count of workers stopped without draining.
|
|
1146
1180
|
*/
|
|
1147
1181
|
private closeWorkers;
|
|
1148
1182
|
/** Close every cached `QueueEvents` in parallel within the budget, swallowing failures. */
|
|
@@ -1221,7 +1255,7 @@ declare function Processor(queueName: string, options?: WorkerOptions): ClassDec
|
|
|
1221
1255
|
* an entry to the accumulated metadata array.
|
|
1222
1256
|
*
|
|
1223
1257
|
* Delivery is at-least-once: a handler may run more than once for the same job
|
|
1224
|
-
* (worker crash, lock expiry, or a shutdown
|
|
1258
|
+
* (worker crash, lock expiry, or a shutdown that outlasts the drain budget). Handlers MUST be
|
|
1225
1259
|
* idempotent — use an idempotency key on writes, prefer upserts over inserts, or
|
|
1226
1260
|
* keep an "already-processed" marker keyed by `job.id`.
|
|
1227
1261
|
*
|
|
@@ -1273,7 +1307,7 @@ type WorkerEventName = 'completed' | 'failed' | 'progress' | 'active' | 'stalled
|
|
|
1273
1307
|
* overwriting each other.
|
|
1274
1308
|
*
|
|
1275
1309
|
* Delivery is at-least-once. A `'stalled'` job — for example after a shutdown
|
|
1276
|
-
*
|
|
1310
|
+
* that outlasts the drain budget, or a lock expiry — is re-run by another worker: this is the
|
|
1277
1311
|
* visible at-least-once path, so handlers must be idempotent. Set `lockDuration`
|
|
1278
1312
|
* comfortably above the worst-case handler runtime to avoid false stalls.
|
|
1279
1313
|
*
|
|
@@ -1490,7 +1524,7 @@ declare const DEFAULT_JOB_OPTIONS: {
|
|
|
1490
1524
|
};
|
|
1491
1525
|
/** Default TTL (ms) for the metrics cache. */
|
|
1492
1526
|
declare const DEFAULT_METRICS_CACHE_TTL_MS: 5000;
|
|
1493
|
-
/** Default window (ms) for in-flight jobs to drain before
|
|
1527
|
+
/** Default window (ms) for in-flight jobs to drain before the worker is stopped on shutdown. */
|
|
1494
1528
|
declare const DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS: 30000;
|
|
1495
1529
|
|
|
1496
1530
|
/**
|
package/dist/server/index.d.ts
CHANGED
|
@@ -105,9 +105,11 @@ interface BymaxQueueModuleOptions {
|
|
|
105
105
|
*/
|
|
106
106
|
commandTimeoutMs?: number;
|
|
107
107
|
/**
|
|
108
|
-
* The deadline, in milliseconds, for one `
|
|
109
|
-
*
|
|
110
|
-
*
|
|
108
|
+
* The deadline, in milliseconds, for one `QueueService` call that reaches Redis (`enqueue`,
|
|
109
|
+
* `getJob`, `getMetrics`, the scheduler, pause and clean calls, and the rest) in either connection
|
|
110
|
+
* mode, including the wait for the client to be ready on a queue's first call. When it passes, the
|
|
111
|
+
* call rejects with `CONNECTION_TIMEOUT`; an `enqueue` may still complete in Redis afterwards, so
|
|
112
|
+
* retry with a stable `jobId` or `deduplication`. Default: 10_000.
|
|
111
113
|
*/
|
|
112
114
|
enqueueTimeoutMs?: number;
|
|
113
115
|
}
|
|
@@ -401,6 +403,14 @@ declare class ConnectionResolver {
|
|
|
401
403
|
getMode(): QueueConnectionMode;
|
|
402
404
|
/** Whether the library owns (and must close) the connection. */
|
|
403
405
|
isOwned(): boolean;
|
|
406
|
+
/**
|
|
407
|
+
* Settle when the client can take a command. While it is still connecting or reconnecting, every
|
|
408
|
+
* caller shares one wait on its `ready` event, so a health check that polls through a long outage
|
|
409
|
+
* adds one listener set to the client, not one per call, and gives it back when Redis returns. A
|
|
410
|
+
* lazy client (`wait`) connects on its first command and a finished one (`end`) never becomes
|
|
411
|
+
* ready, so both are left for the call itself.
|
|
412
|
+
*/
|
|
413
|
+
awaitReady(): Promise<void>;
|
|
404
414
|
/** Close the library-owned connection on shutdown; never touch a BYO client. */
|
|
405
415
|
teardown(): Promise<void>;
|
|
406
416
|
/** Validate and adopt a bring-your-own client for the Queue role. */
|
|
@@ -446,20 +456,27 @@ declare class QueueService {
|
|
|
446
456
|
* @param overrides - Optional per-queue option overrides.
|
|
447
457
|
*/
|
|
448
458
|
getOrCreateQueue<TData = unknown, TResult = unknown>(queueName: string, overrides?: Partial<Omit<QueueOptions, 'connection' | 'prefix'>>): Queue<TData, TResult>;
|
|
449
|
-
/** The error a producer call receives when Redis does not answer within `enqueueTimeoutMs`. */
|
|
450
|
-
private enqueueTimeout;
|
|
451
459
|
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
460
|
+
* Run one Redis call under the per-call deadline (`enqueueTimeoutMs`), reporting every way Redis
|
|
461
|
+
* can fail to answer as the documented `CONNECTION_TIMEOUT`: the deadline passing, an ioredis
|
|
462
|
+
* command timeout, or a call refused because the connection is down.
|
|
463
|
+
*
|
|
464
|
+
* The first call on a queue name waits for the client to be ready through ONE wait shared by all
|
|
465
|
+
* callers, instead of letting BullMQ start its own unbounded wait per call, so a caller that
|
|
466
|
+
* polls through an outage does not pile up listeners. The call runs only if it is still within
|
|
467
|
+
* its deadline when the client is ready; a caller that was told it timed out never has its call
|
|
468
|
+
* run later, which would turn its retry into a duplicate.
|
|
454
469
|
*/
|
|
455
470
|
private call;
|
|
471
|
+
/** Settle when a call on `queueName` may start: at once for a queue that has been used before. */
|
|
472
|
+
private afterReady;
|
|
456
473
|
/** Resolve the raw cached queue (default generics) for internal delegation. */
|
|
457
474
|
private queueFor;
|
|
458
475
|
/**
|
|
459
476
|
* Add a single job to a queue. The queue is created lazily if needed.
|
|
460
477
|
*
|
|
461
478
|
* Delivery is **at-least-once** — a handler may run more than once for the same
|
|
462
|
-
* job (worker crash, lock expiry, or a shutdown
|
|
479
|
+
* job (worker crash, lock expiry, or a shutdown that outlasts the drain budget). Make handlers
|
|
463
480
|
* idempotent: use an idempotency key on writes, prefer upserts over inserts, or
|
|
464
481
|
* keep an "already-processed" marker keyed by `job.id`.
|
|
465
482
|
*
|
|
@@ -580,9 +597,11 @@ declare class QueueService {
|
|
|
580
597
|
*
|
|
581
598
|
* @param queueName - Target queue.
|
|
582
599
|
* @param start - Page start index (inclusive). Default: 0.
|
|
583
|
-
* @param end - Page end index (inclusive). Default: 50.
|
|
600
|
+
* @param end - Page end index (inclusive). Default: 50. The window may span at most
|
|
601
|
+
* `MAX_JOBS_PAGE_SIZE` (1000) entries, and BullMQ's `-1` (everything) is refused.
|
|
584
602
|
* @param asc - Sort ascending by next run time. Default: true.
|
|
585
603
|
* @returns The registered schedulers in the requested page.
|
|
604
|
+
* @throws {QueueException} `INVALID_OPTIONS` when the window is not a bounded range of integers.
|
|
586
605
|
*/
|
|
587
606
|
getJobSchedulers(queueName: string, start?: number, end?: number, asc?: boolean): Promise<Awaited<ReturnType<Queue['getJobSchedulers']>>>;
|
|
588
607
|
/** Pause a queue, halting the processing of new jobs. */
|
|
@@ -643,7 +662,7 @@ declare class FlowService {
|
|
|
643
662
|
#private;
|
|
644
663
|
private readonly logger;
|
|
645
664
|
private readonly producer?;
|
|
646
|
-
constructor(connection: ConnectionResolver, enabled: boolean, prefix: string, telemetry?: Telemetry);
|
|
665
|
+
constructor(connection: ConnectionResolver, enabled: boolean, prefix: string, telemetry?: Telemetry, enqueueTimeoutMs?: number);
|
|
647
666
|
/**
|
|
648
667
|
* Add a flow tree (a parent with its descendant children). The root job
|
|
649
668
|
* becomes processable only after every descendant has completed.
|
|
@@ -661,7 +680,8 @@ declare class FlowService {
|
|
|
661
680
|
* A job whose custom `jobId` already exists is not added again: its node carries the EXISTING
|
|
662
681
|
* id with the data of this call, so the tree does not describe what is stored; call
|
|
663
682
|
* `QueueService.getJob` when you need it.
|
|
664
|
-
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled
|
|
683
|
+
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled; `CONNECTION_TIMEOUT`
|
|
684
|
+
* when Redis does not answer within `enqueueTimeoutMs` (the flow may still have been added).
|
|
665
685
|
*/
|
|
666
686
|
add(flow: FlowJob): Promise<JobNode>;
|
|
667
687
|
/**
|
|
@@ -670,9 +690,17 @@ declare class FlowService {
|
|
|
670
690
|
* @param flows - Flow tree definitions.
|
|
671
691
|
* @returns The root `JobNode` for each flow, in input order.
|
|
672
692
|
* A job whose custom `jobId` already exists is not added again; see {@link FlowService.add}.
|
|
673
|
-
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled
|
|
693
|
+
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled;
|
|
694
|
+
* `BULK_ENQUEUE_FAILED` for more than 1000 flows; `CONNECTION_TIMEOUT` as for
|
|
695
|
+
* {@link FlowService.add}.
|
|
674
696
|
*/
|
|
675
697
|
addBulk(flows: readonly FlowJob[]): Promise<JobNode[]>;
|
|
698
|
+
/**
|
|
699
|
+
* Hold the caller to `enqueueTimeoutMs`, and report a command timeout or a down connection as
|
|
700
|
+
* `CONNECTION_TIMEOUT`. A call that timed out may still have been added: BullMQ is not asked to
|
|
701
|
+
* cancel it.
|
|
702
|
+
*/
|
|
703
|
+
private bounded;
|
|
676
704
|
/** The command deadline of the producer connection, read when a command has timed out. */
|
|
677
705
|
private commandTimeout;
|
|
678
706
|
/**
|
|
@@ -964,8 +992,9 @@ declare class WorkerRegistry {
|
|
|
964
992
|
private guardDuplicate;
|
|
965
993
|
/**
|
|
966
994
|
* Validate tunable options before constructing a Worker.
|
|
967
|
-
* Enforces `concurrency` in `[1, MAX_WORKER_CONCURRENCY]
|
|
968
|
-
* `limiter.max`/`limiter.duration` `>= 1
|
|
995
|
+
* Enforces whole-number `concurrency` in `[1, MAX_WORKER_CONCURRENCY]`, whole-number
|
|
996
|
+
* `limiter.max`/`limiter.duration` `>= 1`, and `lockDuration`/`stalledInterval` within
|
|
997
|
+
* 1000..2^31 - 1.
|
|
969
998
|
*
|
|
970
999
|
* @param opts - The caller-supplied options (may be undefined).
|
|
971
1000
|
* @throws {QueueException} `WORKER_REGISTRATION_FAILED` when values are out of range.
|
|
@@ -1087,9 +1116,9 @@ declare class QueueEventsRegistry {
|
|
|
1087
1116
|
* HTTP server has stopped, it releases what a request can still be using: the
|
|
1088
1117
|
* flow producer, the cached queues, and finally the Queue-role connection.
|
|
1089
1118
|
*
|
|
1090
|
-
* Delivery is at-least-once: when a worker exceeds the drain budget it is
|
|
1091
|
-
*
|
|
1092
|
-
* worker. Handlers must therefore be idempotent, and `lockDuration` should
|
|
1119
|
+
* Delivery is at-least-once: when a worker exceeds the drain budget it is stopped
|
|
1120
|
+
* without waiting for its job, whose lock then expires so the job becomes `stalled`
|
|
1121
|
+
* and is retried by another worker. Handlers must therefore be idempotent, and `lockDuration` should
|
|
1093
1122
|
* comfortably exceed the worst-case handler runtime so healthy long jobs are
|
|
1094
1123
|
* never treated as stalled.
|
|
1095
1124
|
* @layer server/lifecycle
|
|
@@ -1138,11 +1167,16 @@ declare class QueueLifecycle implements OnModuleDestroy, OnApplicationShutdown {
|
|
|
1138
1167
|
*/
|
|
1139
1168
|
onApplicationShutdown(): Promise<void>;
|
|
1140
1169
|
/**
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1170
|
+
* Stop every worker in parallel, each bounded by what is left of the shutdown budget. A worker
|
|
1171
|
+
* is paused first (it stops fetching and waits for its active jobs) and then closed. One that is
|
|
1172
|
+
* still busy when the budget ends is closed with `close(true)`: because `pause` does not start a
|
|
1173
|
+
* close, that is the worker's FIRST close, so it does not wait for the job and stops the lock
|
|
1174
|
+
* renewal that would otherwise keep running and keep the process alive. The job's lock then
|
|
1175
|
+
* expires, and it stalls and is retried elsewhere. Returns how many workers were stopped
|
|
1176
|
+
* without draining.
|
|
1143
1177
|
*
|
|
1144
1178
|
* @param deadline - The epoch millisecond at which the shutdown budget ends.
|
|
1145
|
-
* @returns The count of
|
|
1179
|
+
* @returns The count of workers stopped without draining.
|
|
1146
1180
|
*/
|
|
1147
1181
|
private closeWorkers;
|
|
1148
1182
|
/** Close every cached `QueueEvents` in parallel within the budget, swallowing failures. */
|
|
@@ -1221,7 +1255,7 @@ declare function Processor(queueName: string, options?: WorkerOptions): ClassDec
|
|
|
1221
1255
|
* an entry to the accumulated metadata array.
|
|
1222
1256
|
*
|
|
1223
1257
|
* Delivery is at-least-once: a handler may run more than once for the same job
|
|
1224
|
-
* (worker crash, lock expiry, or a shutdown
|
|
1258
|
+
* (worker crash, lock expiry, or a shutdown that outlasts the drain budget). Handlers MUST be
|
|
1225
1259
|
* idempotent — use an idempotency key on writes, prefer upserts over inserts, or
|
|
1226
1260
|
* keep an "already-processed" marker keyed by `job.id`.
|
|
1227
1261
|
*
|
|
@@ -1273,7 +1307,7 @@ type WorkerEventName = 'completed' | 'failed' | 'progress' | 'active' | 'stalled
|
|
|
1273
1307
|
* overwriting each other.
|
|
1274
1308
|
*
|
|
1275
1309
|
* Delivery is at-least-once. A `'stalled'` job — for example after a shutdown
|
|
1276
|
-
*
|
|
1310
|
+
* that outlasts the drain budget, or a lock expiry — is re-run by another worker: this is the
|
|
1277
1311
|
* visible at-least-once path, so handlers must be idempotent. Set `lockDuration`
|
|
1278
1312
|
* comfortably above the worst-case handler runtime to avoid false stalls.
|
|
1279
1313
|
*
|
|
@@ -1490,7 +1524,7 @@ declare const DEFAULT_JOB_OPTIONS: {
|
|
|
1490
1524
|
};
|
|
1491
1525
|
/** Default TTL (ms) for the metrics cache. */
|
|
1492
1526
|
declare const DEFAULT_METRICS_CACHE_TTL_MS: 5000;
|
|
1493
|
-
/** Default window (ms) for in-flight jobs to drain before
|
|
1527
|
+
/** Default window (ms) for in-flight jobs to drain before the worker is stopped on shutdown. */
|
|
1494
1528
|
declare const DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS: 30000;
|
|
1495
1529
|
|
|
1496
1530
|
/**
|