@bymax-one/nest-queue 1.2.9 → 1.2.11
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 +102 -1
- package/README.md +27 -16
- package/dist/server/index.cjs +59 -484
- package/dist/server/index.d.cts +44 -14
- package/dist/server/index.d.ts +44 -14
- package/dist/server/index.mjs +60 -485
- package/package.json +3 -2
package/dist/server/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _nestjs_common from '@nestjs/common';
|
|
2
|
-
import { ModuleMetadata, Type, DynamicModule, OnModuleDestroy, HttpException, HttpStatus } from '@nestjs/common';
|
|
2
|
+
import { ModuleMetadata, Type, DynamicModule, OnModuleDestroy, OnApplicationShutdown, HttpException, HttpStatus } from '@nestjs/common';
|
|
3
3
|
import { JobsOptions, QueueOptions, Telemetry, BulkJobOptions, Queue, Job, FlowJob, JobNode, FlowProducer, Worker, QueueEvents } from 'bullmq';
|
|
4
4
|
export { FlowJob, FlowProducer, Job, JobNode, JobSchedulerJson, JobsOptions, Queue, QueueEvents, SandboxedJob, Telemetry, Worker } from 'bullmq';
|
|
5
5
|
import { Redis, RedisOptions } from 'ioredis';
|
|
@@ -453,7 +453,11 @@ declare class QueueService {
|
|
|
453
453
|
* @param jobName - Job identifier used by `@Process` to dispatch.
|
|
454
454
|
* @param data - Typed job payload.
|
|
455
455
|
* @param options - Per-job BullMQ options (priority, delay, `jobId`, `deduplication`, ...).
|
|
456
|
-
* @returns The
|
|
456
|
+
* @returns The job BullMQ returned. When a custom `jobId` already exists, or a `deduplication`
|
|
457
|
+
* rule keeps the job already there (one with `replace` swaps it for the new job), nothing new
|
|
458
|
+
* is added: BullMQ answers with the id of the EXISTING job and the data and options of THIS
|
|
459
|
+
* call, so the returned object does not describe what is stored. Call
|
|
460
|
+
* {@link QueueService.getJob} when you need the stored job.
|
|
457
461
|
* @example Throttle: at most one reindex per term every 5 seconds. Both variable
|
|
458
462
|
* fields are percent-encoded, so no other tenant/term pair can build this key.
|
|
459
463
|
* const dedupId = `${encodeURIComponent(tenantId)}:reindex:${encodeURIComponent(term)}`
|
|
@@ -470,6 +474,9 @@ declare class QueueService {
|
|
|
470
474
|
*
|
|
471
475
|
* @param queueName - Target queue.
|
|
472
476
|
* @param jobs - Job descriptors (length must not exceed the bulk size cap).
|
|
477
|
+
* @returns The jobs BullMQ returned, in input order. An entry whose custom `jobId` already
|
|
478
|
+
* exists is not added again: it carries the EXISTING id with the data of this call, as for
|
|
479
|
+
* {@link QueueService.enqueue}.
|
|
473
480
|
*/
|
|
474
481
|
enqueueBulk<TData = unknown, TResult = unknown>(queueName: string, jobs: readonly BulkJob<TData>[]): Promise<TypedJob<TData, TResult>[]>;
|
|
475
482
|
/**
|
|
@@ -501,9 +508,9 @@ declare class QueueService {
|
|
|
501
508
|
* never duplicates it. This supersedes the repeatable-jobs surface removed in
|
|
502
509
|
* BullMQ v6.
|
|
503
510
|
*
|
|
504
|
-
* The schedule is
|
|
505
|
-
*
|
|
506
|
-
*
|
|
511
|
+
* The schedule is validated first, and a cron pattern BullMQ's parser rejects
|
|
512
|
+
* is `INVALID_REPEAT_OPTIONS` (400) before Redis is asked; any other failure
|
|
513
|
+
* propagates as it is.
|
|
507
514
|
*
|
|
508
515
|
* @param queueName - Target queue.
|
|
509
516
|
* @param schedulerId - Stable, unique scheduler identifier (the upsert key).
|
|
@@ -607,6 +614,9 @@ declare class FlowService {
|
|
|
607
614
|
*
|
|
608
615
|
* @param flow - Flow tree definition.
|
|
609
616
|
* @returns The root `JobNode` containing the created job and its children.
|
|
617
|
+
* A job whose custom `jobId` already exists is not added again: its node carries the EXISTING
|
|
618
|
+
* id with the data of this call, so the tree does not describe what is stored; call
|
|
619
|
+
* `QueueService.getJob` when you need it.
|
|
610
620
|
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled.
|
|
611
621
|
*/
|
|
612
622
|
add(flow: FlowJob): Promise<JobNode>;
|
|
@@ -615,6 +625,7 @@ declare class FlowService {
|
|
|
615
625
|
*
|
|
616
626
|
* @param flows - Flow tree definitions.
|
|
617
627
|
* @returns The root `JobNode` for each flow, in input order.
|
|
628
|
+
* A job whose custom `jobId` already exists is not added again; see {@link FlowService.add}.
|
|
618
629
|
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled.
|
|
619
630
|
*/
|
|
620
631
|
addBulk(flows: readonly FlowJob[]): Promise<JobNode[]>;
|
|
@@ -1002,9 +1013,12 @@ declare class QueueEventsRegistry {
|
|
|
1002
1013
|
|
|
1003
1014
|
/**
|
|
1004
1015
|
* @fileoverview `QueueLifecycle` — the single, ordered graceful-shutdown
|
|
1005
|
-
* orchestrator
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1016
|
+
* orchestrator, split across the two NestJS hooks that bracket the HTTP server.
|
|
1017
|
+
* On `onModuleDestroy` it stops consumption: it drains every worker within a
|
|
1018
|
+
* bounded budget, then closes queue-events and the connections the library
|
|
1019
|
+
* opened for them. On `onApplicationShutdown`, which NestJS runs only after the
|
|
1020
|
+
* HTTP server has stopped, it releases what a request can still be using: the
|
|
1021
|
+
* flow producer, the cached queues, and finally the Queue-role connection.
|
|
1008
1022
|
*
|
|
1009
1023
|
* Delivery is at-least-once: when a worker exceeds the drain budget it is
|
|
1010
1024
|
* force-closed and its in-flight job becomes `stalled` and is retried by another
|
|
@@ -1017,16 +1031,22 @@ declare class QueueEventsRegistry {
|
|
|
1017
1031
|
/**
|
|
1018
1032
|
* Ordered graceful-shutdown service. Implementing the protocol in one place
|
|
1019
1033
|
* guarantees the teardown order — workers drain first, then queue-events, then
|
|
1020
|
-
* the duplicated connections
|
|
1021
|
-
* the Queue-role connection. Every step
|
|
1022
|
-
* failure never aborts the rest of the
|
|
1034
|
+
* the duplicated connections; once the HTTP server has stopped, the flow
|
|
1035
|
+
* producer, the queues, and finally the Queue-role connection. Every step
|
|
1036
|
+
* swallows its own errors so a single failure never aborts the rest of the
|
|
1037
|
+
* sequence.
|
|
1038
|
+
*
|
|
1039
|
+
* Why two hooks: NestJS runs `onModuleDestroy` before it stops the HTTP server,
|
|
1040
|
+
* so a request that is still being served can enqueue a job after that hook has
|
|
1041
|
+
* returned. The producer side (queues, flow producer, Queue-role connection)
|
|
1042
|
+
* therefore waits for `onApplicationShutdown`, while consumption stops early.
|
|
1023
1043
|
*
|
|
1024
1044
|
* Connection ownership: in **Mode B** the library-owned Queue-role client is
|
|
1025
1045
|
* quit by the connection resolver; in **Mode A** that step is a no-op and only
|
|
1026
1046
|
* the duplicated worker/queue-events connections the library created are closed
|
|
1027
1047
|
* — the consumer's shared client is never touched.
|
|
1028
1048
|
*/
|
|
1029
|
-
declare class QueueLifecycle implements OnModuleDestroy {
|
|
1049
|
+
declare class QueueLifecycle implements OnModuleDestroy, OnApplicationShutdown {
|
|
1030
1050
|
private readonly workers;
|
|
1031
1051
|
private readonly events;
|
|
1032
1052
|
private readonly queues;
|
|
@@ -1034,12 +1054,22 @@ declare class QueueLifecycle implements OnModuleDestroy {
|
|
|
1034
1054
|
private readonly connection;
|
|
1035
1055
|
private readonly resolved;
|
|
1036
1056
|
private readonly logger;
|
|
1057
|
+
private startedAt;
|
|
1058
|
+
private forcedWorkers;
|
|
1037
1059
|
constructor(workers: WorkerRegistry, events: QueueEventsRegistry, queues: QueueService, flow: FlowService, connection: ConnectionResolver, resolved: ResolvedQueueOptions);
|
|
1038
1060
|
/**
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1061
|
+
* Stop consumption: drain the workers within the bounded budget, then close
|
|
1062
|
+
* queue-events and the connections the library opened for them. Called by
|
|
1063
|
+
* NestJS when the application context closes (e.g. on `SIGTERM` with shutdown
|
|
1064
|
+
* hooks enabled), before the HTTP server stops.
|
|
1041
1065
|
*/
|
|
1042
1066
|
onModuleDestroy(): Promise<void>;
|
|
1067
|
+
/**
|
|
1068
|
+
* Release the producer side once the HTTP server has stopped: the optional
|
|
1069
|
+
* queue drain, the flow producer, the cached queues, and the Queue-role
|
|
1070
|
+
* connection, then log the total shutdown time.
|
|
1071
|
+
*/
|
|
1072
|
+
onApplicationShutdown(): Promise<void>;
|
|
1043
1073
|
/**
|
|
1044
1074
|
* Close every worker with a bounded drain, force-closing any that exceed the
|
|
1045
1075
|
* budget. Returns the number of workers that had to be force-closed.
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _nestjs_common from '@nestjs/common';
|
|
2
|
-
import { ModuleMetadata, Type, DynamicModule, OnModuleDestroy, HttpException, HttpStatus } from '@nestjs/common';
|
|
2
|
+
import { ModuleMetadata, Type, DynamicModule, OnModuleDestroy, OnApplicationShutdown, HttpException, HttpStatus } from '@nestjs/common';
|
|
3
3
|
import { JobsOptions, QueueOptions, Telemetry, BulkJobOptions, Queue, Job, FlowJob, JobNode, FlowProducer, Worker, QueueEvents } from 'bullmq';
|
|
4
4
|
export { FlowJob, FlowProducer, Job, JobNode, JobSchedulerJson, JobsOptions, Queue, QueueEvents, SandboxedJob, Telemetry, Worker } from 'bullmq';
|
|
5
5
|
import { Redis, RedisOptions } from 'ioredis';
|
|
@@ -453,7 +453,11 @@ declare class QueueService {
|
|
|
453
453
|
* @param jobName - Job identifier used by `@Process` to dispatch.
|
|
454
454
|
* @param data - Typed job payload.
|
|
455
455
|
* @param options - Per-job BullMQ options (priority, delay, `jobId`, `deduplication`, ...).
|
|
456
|
-
* @returns The
|
|
456
|
+
* @returns The job BullMQ returned. When a custom `jobId` already exists, or a `deduplication`
|
|
457
|
+
* rule keeps the job already there (one with `replace` swaps it for the new job), nothing new
|
|
458
|
+
* is added: BullMQ answers with the id of the EXISTING job and the data and options of THIS
|
|
459
|
+
* call, so the returned object does not describe what is stored. Call
|
|
460
|
+
* {@link QueueService.getJob} when you need the stored job.
|
|
457
461
|
* @example Throttle: at most one reindex per term every 5 seconds. Both variable
|
|
458
462
|
* fields are percent-encoded, so no other tenant/term pair can build this key.
|
|
459
463
|
* const dedupId = `${encodeURIComponent(tenantId)}:reindex:${encodeURIComponent(term)}`
|
|
@@ -470,6 +474,9 @@ declare class QueueService {
|
|
|
470
474
|
*
|
|
471
475
|
* @param queueName - Target queue.
|
|
472
476
|
* @param jobs - Job descriptors (length must not exceed the bulk size cap).
|
|
477
|
+
* @returns The jobs BullMQ returned, in input order. An entry whose custom `jobId` already
|
|
478
|
+
* exists is not added again: it carries the EXISTING id with the data of this call, as for
|
|
479
|
+
* {@link QueueService.enqueue}.
|
|
473
480
|
*/
|
|
474
481
|
enqueueBulk<TData = unknown, TResult = unknown>(queueName: string, jobs: readonly BulkJob<TData>[]): Promise<TypedJob<TData, TResult>[]>;
|
|
475
482
|
/**
|
|
@@ -501,9 +508,9 @@ declare class QueueService {
|
|
|
501
508
|
* never duplicates it. This supersedes the repeatable-jobs surface removed in
|
|
502
509
|
* BullMQ v6.
|
|
503
510
|
*
|
|
504
|
-
* The schedule is
|
|
505
|
-
*
|
|
506
|
-
*
|
|
511
|
+
* The schedule is validated first, and a cron pattern BullMQ's parser rejects
|
|
512
|
+
* is `INVALID_REPEAT_OPTIONS` (400) before Redis is asked; any other failure
|
|
513
|
+
* propagates as it is.
|
|
507
514
|
*
|
|
508
515
|
* @param queueName - Target queue.
|
|
509
516
|
* @param schedulerId - Stable, unique scheduler identifier (the upsert key).
|
|
@@ -607,6 +614,9 @@ declare class FlowService {
|
|
|
607
614
|
*
|
|
608
615
|
* @param flow - Flow tree definition.
|
|
609
616
|
* @returns The root `JobNode` containing the created job and its children.
|
|
617
|
+
* A job whose custom `jobId` already exists is not added again: its node carries the EXISTING
|
|
618
|
+
* id with the data of this call, so the tree does not describe what is stored; call
|
|
619
|
+
* `QueueService.getJob` when you need it.
|
|
610
620
|
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled.
|
|
611
621
|
*/
|
|
612
622
|
add(flow: FlowJob): Promise<JobNode>;
|
|
@@ -615,6 +625,7 @@ declare class FlowService {
|
|
|
615
625
|
*
|
|
616
626
|
* @param flows - Flow tree definitions.
|
|
617
627
|
* @returns The root `JobNode` for each flow, in input order.
|
|
628
|
+
* A job whose custom `jobId` already exists is not added again; see {@link FlowService.add}.
|
|
618
629
|
* @throws {QueueException} `FLOW_DISABLED` (503) when flows are not enabled.
|
|
619
630
|
*/
|
|
620
631
|
addBulk(flows: readonly FlowJob[]): Promise<JobNode[]>;
|
|
@@ -1002,9 +1013,12 @@ declare class QueueEventsRegistry {
|
|
|
1002
1013
|
|
|
1003
1014
|
/**
|
|
1004
1015
|
* @fileoverview `QueueLifecycle` — the single, ordered graceful-shutdown
|
|
1005
|
-
* orchestrator
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1016
|
+
* orchestrator, split across the two NestJS hooks that bracket the HTTP server.
|
|
1017
|
+
* On `onModuleDestroy` it stops consumption: it drains every worker within a
|
|
1018
|
+
* bounded budget, then closes queue-events and the connections the library
|
|
1019
|
+
* opened for them. On `onApplicationShutdown`, which NestJS runs only after the
|
|
1020
|
+
* HTTP server has stopped, it releases what a request can still be using: the
|
|
1021
|
+
* flow producer, the cached queues, and finally the Queue-role connection.
|
|
1008
1022
|
*
|
|
1009
1023
|
* Delivery is at-least-once: when a worker exceeds the drain budget it is
|
|
1010
1024
|
* force-closed and its in-flight job becomes `stalled` and is retried by another
|
|
@@ -1017,16 +1031,22 @@ declare class QueueEventsRegistry {
|
|
|
1017
1031
|
/**
|
|
1018
1032
|
* Ordered graceful-shutdown service. Implementing the protocol in one place
|
|
1019
1033
|
* guarantees the teardown order — workers drain first, then queue-events, then
|
|
1020
|
-
* the duplicated connections
|
|
1021
|
-
* the Queue-role connection. Every step
|
|
1022
|
-
* failure never aborts the rest of the
|
|
1034
|
+
* the duplicated connections; once the HTTP server has stopped, the flow
|
|
1035
|
+
* producer, the queues, and finally the Queue-role connection. Every step
|
|
1036
|
+
* swallows its own errors so a single failure never aborts the rest of the
|
|
1037
|
+
* sequence.
|
|
1038
|
+
*
|
|
1039
|
+
* Why two hooks: NestJS runs `onModuleDestroy` before it stops the HTTP server,
|
|
1040
|
+
* so a request that is still being served can enqueue a job after that hook has
|
|
1041
|
+
* returned. The producer side (queues, flow producer, Queue-role connection)
|
|
1042
|
+
* therefore waits for `onApplicationShutdown`, while consumption stops early.
|
|
1023
1043
|
*
|
|
1024
1044
|
* Connection ownership: in **Mode B** the library-owned Queue-role client is
|
|
1025
1045
|
* quit by the connection resolver; in **Mode A** that step is a no-op and only
|
|
1026
1046
|
* the duplicated worker/queue-events connections the library created are closed
|
|
1027
1047
|
* — the consumer's shared client is never touched.
|
|
1028
1048
|
*/
|
|
1029
|
-
declare class QueueLifecycle implements OnModuleDestroy {
|
|
1049
|
+
declare class QueueLifecycle implements OnModuleDestroy, OnApplicationShutdown {
|
|
1030
1050
|
private readonly workers;
|
|
1031
1051
|
private readonly events;
|
|
1032
1052
|
private readonly queues;
|
|
@@ -1034,12 +1054,22 @@ declare class QueueLifecycle implements OnModuleDestroy {
|
|
|
1034
1054
|
private readonly connection;
|
|
1035
1055
|
private readonly resolved;
|
|
1036
1056
|
private readonly logger;
|
|
1057
|
+
private startedAt;
|
|
1058
|
+
private forcedWorkers;
|
|
1037
1059
|
constructor(workers: WorkerRegistry, events: QueueEventsRegistry, queues: QueueService, flow: FlowService, connection: ConnectionResolver, resolved: ResolvedQueueOptions);
|
|
1038
1060
|
/**
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1061
|
+
* Stop consumption: drain the workers within the bounded budget, then close
|
|
1062
|
+
* queue-events and the connections the library opened for them. Called by
|
|
1063
|
+
* NestJS when the application context closes (e.g. on `SIGTERM` with shutdown
|
|
1064
|
+
* hooks enabled), before the HTTP server stops.
|
|
1041
1065
|
*/
|
|
1042
1066
|
onModuleDestroy(): Promise<void>;
|
|
1067
|
+
/**
|
|
1068
|
+
* Release the producer side once the HTTP server has stopped: the optional
|
|
1069
|
+
* queue drain, the flow producer, the cached queues, and the Queue-role
|
|
1070
|
+
* connection, then log the total shutdown time.
|
|
1071
|
+
*/
|
|
1072
|
+
onApplicationShutdown(): Promise<void>;
|
|
1043
1073
|
/**
|
|
1044
1074
|
* Close every worker with a bounded drain, force-closing any that exceed the
|
|
1045
1075
|
* budget. Returns the number of workers that had to be force-closed.
|