@vercube/queue 1.3.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/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/QueueStrategy-DwLPpfFM.mjs +237 -0
- package/dist/QueueStrategy-saWSBeU6.d.mts +715 -0
- package/dist/Strategies/BullMQStrategy.d.mts +161 -0
- package/dist/Strategies/BullMQStrategy.mjs +328 -0
- package/dist/Strategies/KafkaStrategy.d.mts +152 -0
- package/dist/Strategies/KafkaStrategy.mjs +280 -0
- package/dist/Strategies/MemoryStrategy.d.mts +139 -0
- package/dist/Strategies/MemoryStrategy.mjs +305 -0
- package/dist/Strategies/RabbitMQStrategy.d.mts +205 -0
- package/dist/Strategies/RabbitMQStrategy.mjs +388 -0
- package/dist/decorate-C0p0FnUM.mjs +25 -0
- package/dist/index.d.mts +953 -0
- package/dist/index.mjs +1719 -0
- package/package.json +54 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,953 @@
|
|
|
1
|
+
import { n as QueueTypes, t as QueueStrategy } from "./QueueStrategy-saWSBeU6.mjs";
|
|
2
|
+
import { BaseDecorator, Container } from "@vercube/di";
|
|
3
|
+
import { Logger } from "@vercube/logger";
|
|
4
|
+
import { App, BasePlugin, ValidationProvider } from "@vercube/core";
|
|
5
|
+
//#region src/Decorators/AnyJob.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Declares the decorated method as the handler of every job of the queue that no
|
|
8
|
+
* `@Job()` claims.
|
|
9
|
+
*
|
|
10
|
+
* A handler registered for a job name always wins, so `@AnyJob()` is the fallback
|
|
11
|
+
* rather than a replacement. It is what makes a queue somebody else fills
|
|
12
|
+
* consumable: messages produced outside this module carry no job name, and would
|
|
13
|
+
* otherwise be reported as unhandled.
|
|
14
|
+
*
|
|
15
|
+
* The real job name is on the context, so the handler can still branch on it.
|
|
16
|
+
* Only one `@AnyJob()` per queue is allowed, like any other handler.
|
|
17
|
+
*
|
|
18
|
+
* @param {QueueTypes.HandlerOptions} [options] - Retries, timeout and payload schema of this handler
|
|
19
|
+
* @returns {Function} The method decorator
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* // a queue filled by another application, whose messages carry no job name
|
|
24
|
+
* @Consumer({ queue: 'legacy-events' })
|
|
25
|
+
* export class LegacyConsumer {
|
|
26
|
+
* @AnyJob({ attempts: 3 })
|
|
27
|
+
* public async handle(payload: unknown, context: QueueTypes.JobContext): Promise<void> {
|
|
28
|
+
* await this.gEvents.ingest(payload, context.job);
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* // known jobs handled on their own, everything else swept up
|
|
36
|
+
* @Consumer({ queue: 'emails' })
|
|
37
|
+
* export class EmailConsumer {
|
|
38
|
+
* @Job('welcome')
|
|
39
|
+
* public async welcome(payload: Welcome): Promise<void> {}
|
|
40
|
+
*
|
|
41
|
+
* @AnyJob()
|
|
42
|
+
* public async rest(payload: unknown, context: QueueTypes.JobContext): Promise<void> {
|
|
43
|
+
* context.logger?.warn(`unrecognised job ${context.job}`);
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function AnyJob(options?: QueueTypes.HandlerOptions): Function;
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/Decorators/Consumer.d.ts
|
|
51
|
+
/**
|
|
52
|
+
* Declares a class as the consumer of a queue.
|
|
53
|
+
*
|
|
54
|
+
* The class itself does nothing until it is bound in the container: that is when
|
|
55
|
+
* its `@Job()` methods register themselves and the queue starts being consumed.
|
|
56
|
+
* Options declared here become the defaults of every handler in the class.
|
|
57
|
+
*
|
|
58
|
+
* @param {QueueTypes.ConsumerOptions} options - Queue to consume, its concurrency and the handler defaults
|
|
59
|
+
* @returns {Function} The class decorator
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* @Consumer({ queue: 'emails', concurrency: 5 })
|
|
64
|
+
* export class EmailConsumer {
|
|
65
|
+
* @Job('welcome')
|
|
66
|
+
* public async welcome(payload: { userId: string }): Promise<void> {
|
|
67
|
+
* await this.mailer.sendWelcome(payload.userId);
|
|
68
|
+
* }
|
|
69
|
+
* }
|
|
70
|
+
*
|
|
71
|
+
* // in the container setup
|
|
72
|
+
* container.bind(EmailConsumer);
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* // defaults for every handler of the class, overridable per job
|
|
78
|
+
* @Consumer({ queue: 'reports', strategy: 'kafka', attempts: 3, timeout: 30_000 })
|
|
79
|
+
* export class ReportConsumer {}
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function Consumer(options: QueueTypes.ConsumerOptions): Function;
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/Decorators/Job.d.ts
|
|
85
|
+
/** Options the `@Job()` decorator is created with. */
|
|
86
|
+
interface JobDecoratorOptions {
|
|
87
|
+
/** Name of the job the method handles. */
|
|
88
|
+
name: string;
|
|
89
|
+
/** Consumer-side options of this handler. */
|
|
90
|
+
options: QueueTypes.HandlerOptions;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Registers the decorated method as the handler of a single job.
|
|
94
|
+
* Runs when the container instantiates the consumer class.
|
|
95
|
+
*/
|
|
96
|
+
export declare class JobDecorator extends BaseDecorator<JobDecoratorOptions> {
|
|
97
|
+
/** Queue manager the handler is registered with */
|
|
98
|
+
private gQueueManager;
|
|
99
|
+
/** Logger instance */
|
|
100
|
+
private gLogger;
|
|
101
|
+
/** The registration handed to the manager, kept so it can be removed again */
|
|
102
|
+
private fRegistration;
|
|
103
|
+
/**
|
|
104
|
+
* Registers the handler with the queue manager.
|
|
105
|
+
*
|
|
106
|
+
* @returns {void}
|
|
107
|
+
*/
|
|
108
|
+
created(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Removes the handler again, so rebinding the consumer class does not collide
|
|
111
|
+
* with the handler its previous instance registered.
|
|
112
|
+
*
|
|
113
|
+
* @returns {void}
|
|
114
|
+
*/
|
|
115
|
+
destroyed(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Reports a consumer that cannot be wired up.
|
|
118
|
+
*
|
|
119
|
+
* @param {string} message - What is wrong
|
|
120
|
+
* @returns {void}
|
|
121
|
+
*/
|
|
122
|
+
private warn;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Declares the decorated method as the handler of a job.
|
|
126
|
+
*
|
|
127
|
+
* The method receives the job payload as its first argument and a
|
|
128
|
+
* {@link QueueTypes.JobContext} as its second. Returning marks the job as done,
|
|
129
|
+
* throwing marks the attempt as failed and hands it to the retry policy.
|
|
130
|
+
*
|
|
131
|
+
* Options given here override the defaults of the `@Consumer()` class. To handle
|
|
132
|
+
* everything the queue carries beyond the named jobs, see `@AnyJob()`.
|
|
133
|
+
*
|
|
134
|
+
* @param {string} name - Name of the job, as used when adding it to the queue
|
|
135
|
+
* @param {QueueTypes.HandlerOptions} [options] - Retries, timeout and payload schema of this handler
|
|
136
|
+
* @returns {Function} The method decorator
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* @Consumer({ queue: 'emails' })
|
|
141
|
+
* export class EmailConsumer {
|
|
142
|
+
* @Job('welcome')
|
|
143
|
+
* public async welcome(payload: { userId: string }): Promise<void> {
|
|
144
|
+
* await this.mailer.sendWelcome(payload.userId);
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* // three attempts with a growing delay, a validated payload and a hard time limit
|
|
152
|
+
* @Job('digest', {
|
|
153
|
+
* attempts: 3,
|
|
154
|
+
* backoff: { type: 'exponential', delay: 1000 },
|
|
155
|
+
* timeout: 30_000,
|
|
156
|
+
* schema: DigestSchema,
|
|
157
|
+
* })
|
|
158
|
+
* public async digest(payload: Digest, context: QueueTypes.JobContext<Digest>): Promise<void> {
|
|
159
|
+
* context.logger?.info(`attempt ${context.attempt} of ${context.attempts}`);
|
|
160
|
+
* await context.updateProgress(50);
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export declare function Job(name: string, options?: QueueTypes.HandlerOptions): Function;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/Decorators/OnJobCompleted.d.ts
|
|
167
|
+
/**
|
|
168
|
+
* Runs the decorated method after a job of the consumer's queue completed.
|
|
169
|
+
*
|
|
170
|
+
* The hook receives the {@link QueueTypes.JobContext} of the finished job. It
|
|
171
|
+
* never changes the outcome of that job: a throwing hook is logged and forgotten.
|
|
172
|
+
*
|
|
173
|
+
* @param {object} [options] - Narrows the hook down to a single job
|
|
174
|
+
* @param {string} [options.job] - Name of the only job to listen for, every job of the queue by default
|
|
175
|
+
* @returns {Function} The method decorator
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* @Consumer({ queue: 'emails' })
|
|
180
|
+
* export class EmailConsumer {
|
|
181
|
+
* @Job('welcome')
|
|
182
|
+
* public async welcome(payload: { userId: string }): Promise<void> {}
|
|
183
|
+
*
|
|
184
|
+
* @OnJobCompleted()
|
|
185
|
+
* public async sent(context: QueueTypes.JobContext): Promise<void> {
|
|
186
|
+
* this.metrics.increment(`emails.${context.job}.sent`);
|
|
187
|
+
* }
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export declare function OnJobCompleted(options?: {
|
|
192
|
+
job?: string;
|
|
193
|
+
}): Function;
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/Decorators/OnJobFailed.d.ts
|
|
196
|
+
/**
|
|
197
|
+
* Runs the decorated method after an attempt of a job of the consumer's queue threw.
|
|
198
|
+
*
|
|
199
|
+
* The hook receives the error and the {@link QueueTypes.JobContext} of the failed
|
|
200
|
+
* attempt, so it can tell a retry from a final failure by comparing
|
|
201
|
+
* `context.attempt` with `context.attempts`. It never changes the outcome of the
|
|
202
|
+
* job: a throwing hook is logged and forgotten.
|
|
203
|
+
*
|
|
204
|
+
* @param {object} [options] - Narrows the hook down to a single job
|
|
205
|
+
* @param {string} [options.job] - Name of the only job to listen for, every job of the queue by default
|
|
206
|
+
* @returns {Function} The method decorator
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* @Consumer({ queue: 'emails' })
|
|
211
|
+
* export class EmailConsumer {
|
|
212
|
+
* @Job('welcome', { attempts: 3 })
|
|
213
|
+
* public async welcome(payload: { userId: string }): Promise<void> {}
|
|
214
|
+
*
|
|
215
|
+
* @OnJobFailed()
|
|
216
|
+
* public async failed(error: Error, context: QueueTypes.JobContext): Promise<void> {
|
|
217
|
+
* if (context.attempt === context.attempts) {
|
|
218
|
+
* await this.alerts.report(error, context.id);
|
|
219
|
+
* }
|
|
220
|
+
* }
|
|
221
|
+
* }
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export declare function OnJobFailed(options?: {
|
|
225
|
+
job?: string;
|
|
226
|
+
}): Function;
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/Plugins/QueuePlugin.d.ts
|
|
229
|
+
/**
|
|
230
|
+
* Queue Plugin for Vercube framework
|
|
231
|
+
*
|
|
232
|
+
* Binds the {@link QueueManager}, mounts the strategies it is given and lets the
|
|
233
|
+
* `@Consumer()` classes bound in the container start consuming once the
|
|
234
|
+
* application is up. Consumer classes themselves stay in your hands: bind them
|
|
235
|
+
* where you bind your controllers.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* import { defineConfig } from '@vercube/core';
|
|
240
|
+
* import { QueuePlugin } from '@vercube/queue';
|
|
241
|
+
* import { BullMQStrategy } from '@vercube/queue/strategies/BullMQStrategy';
|
|
242
|
+
*
|
|
243
|
+
* export default defineConfig({
|
|
244
|
+
* plugins: [
|
|
245
|
+
* [QueuePlugin, {
|
|
246
|
+
* strategies: [{ strategy: BullMQStrategy, initOptions: { connection: { host: '127.0.0.1', port: 6379 } } }],
|
|
247
|
+
* }],
|
|
248
|
+
* ],
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* // a web process that only publishes jobs
|
|
255
|
+
* app.addPlugin(QueuePlugin, {
|
|
256
|
+
* autoStart: false,
|
|
257
|
+
* strategies: [{ strategy: MemoryStrategy }],
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @see {@link https://vercube.dev} for full documentation
|
|
262
|
+
*/
|
|
263
|
+
export declare class QueuePlugin extends BasePlugin<QueueTypes.PluginOptions> {
|
|
264
|
+
/**
|
|
265
|
+
* The name of the plugin.
|
|
266
|
+
* @override
|
|
267
|
+
*/
|
|
268
|
+
name: string;
|
|
269
|
+
/**
|
|
270
|
+
* Binds the queue manager and mounts every configured strategy.
|
|
271
|
+
*
|
|
272
|
+
* Registering the plugin more than once, which happens as soon as it is listed
|
|
273
|
+
* both in the config and in `app.addPlugin()`, is harmless: the manager is
|
|
274
|
+
* bound once, settings are merged, and a name that is already mounted is left
|
|
275
|
+
* alone. Rebinding it would drop the settings and the strategies of whoever
|
|
276
|
+
* registered first.
|
|
277
|
+
*
|
|
278
|
+
* @param {App} app - The application instance
|
|
279
|
+
* @param {QueueTypes.PluginOptions} [options] - Strategies to mount and manager-wide settings
|
|
280
|
+
* @returns {Promise<void>} Resolves once every strategy is mounted
|
|
281
|
+
* @override
|
|
282
|
+
*/
|
|
283
|
+
use(app: App, options?: QueueTypes.PluginOptions): Promise<void>;
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region src/Errors/QueueError.d.ts
|
|
287
|
+
/**
|
|
288
|
+
* Error thrown by the queue module.
|
|
289
|
+
* Wraps transport errors with a stable shape so callers can tell what failed
|
|
290
|
+
* and whether the job is worth retrying.
|
|
291
|
+
*/
|
|
292
|
+
export declare class QueueError extends Error {
|
|
293
|
+
/** The original error that caused this one. */
|
|
294
|
+
readonly cause?: Error;
|
|
295
|
+
/** The queue operation that failed, for example `publish` or `consume`. */
|
|
296
|
+
readonly operation: string;
|
|
297
|
+
/** Whether processing the job again could succeed. */
|
|
298
|
+
readonly retryable: boolean;
|
|
299
|
+
/** Additional non-sensitive context about the failure. */
|
|
300
|
+
readonly metadata?: Record<string, unknown>;
|
|
301
|
+
/**
|
|
302
|
+
* @param message - Human readable description of the failure.
|
|
303
|
+
* @param operation - Queue operation that failed.
|
|
304
|
+
* @param cause - Underlying error, when there is one.
|
|
305
|
+
* @param metadata - Additional non-sensitive context.
|
|
306
|
+
* @param retryable - Whether processing the job again could succeed, defaults to true.
|
|
307
|
+
*/
|
|
308
|
+
constructor(message: string, operation: string, cause?: Error, metadata?: Record<string, unknown>, retryable?: boolean);
|
|
309
|
+
}
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/Services/QueueManager.d.ts
|
|
312
|
+
/**
|
|
313
|
+
* Central entry point of the queue module.
|
|
314
|
+
*
|
|
315
|
+
* The manager owns the mounted strategies, the handlers registered by the
|
|
316
|
+
* decorators and everything that has to behave the same across transports:
|
|
317
|
+
* routing a job to its handler, validating payloads, retries, timeouts,
|
|
318
|
+
* lifecycle hooks and the counters the devtools read.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```ts
|
|
322
|
+
* container.bind(QueueManager);
|
|
323
|
+
*
|
|
324
|
+
* const queue = container.get(QueueManager);
|
|
325
|
+
* await queue.mount({ strategy: MemoryStrategy });
|
|
326
|
+
*
|
|
327
|
+
* await queue.add({ queue: 'emails', job: 'welcome', payload: { userId: '1' } });
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
export declare class QueueManager {
|
|
331
|
+
/** Container instance */
|
|
332
|
+
protected gContainer: Container;
|
|
333
|
+
/** Logger instance */
|
|
334
|
+
protected gLogger: Logger | null;
|
|
335
|
+
/** Validation provider, needed only by handlers declaring a schema */
|
|
336
|
+
protected gValidation: ValidationProvider | null;
|
|
337
|
+
/** Mounted strategies, indexed by mount name */
|
|
338
|
+
protected fStrategies: Map<string, QueueTypes.MountedStrategy<any>>;
|
|
339
|
+
/** Registered handlers, indexed by strategy, queue and job name */
|
|
340
|
+
protected fRegistrations: Map<string, QueueTypes.Registration>;
|
|
341
|
+
/** Registered lifecycle hooks */
|
|
342
|
+
protected fHooks: {
|
|
343
|
+
completed: QueueTypes.HookRegistration[];
|
|
344
|
+
failed: QueueTypes.HookRegistration[];
|
|
345
|
+
};
|
|
346
|
+
/** Running consumers, indexed by strategy and queue */
|
|
347
|
+
protected fConsumers: Map<string, {
|
|
348
|
+
handle: QueueTypes.ConsumerHandle;
|
|
349
|
+
concurrency: number;
|
|
350
|
+
}>;
|
|
351
|
+
/** Per-queue counters, indexed by strategy and queue */
|
|
352
|
+
protected fMetrics: Map<string, QueueTypes.QueueMetrics>;
|
|
353
|
+
/** Recently processed jobs, newest first */
|
|
354
|
+
protected fEvents: QueueTypes.JobEvent[];
|
|
355
|
+
/** Manager-wide settings */
|
|
356
|
+
protected fDefaults: Required<QueueTypes.Defaults>;
|
|
357
|
+
/** Whether consumers should be running */
|
|
358
|
+
protected fStarted: boolean;
|
|
359
|
+
/** Serializes start, stop and mount work so consumers are never started twice */
|
|
360
|
+
protected fTail: Promise<void>;
|
|
361
|
+
/** Retries waiting for their backoff to elapse */
|
|
362
|
+
protected fPendingRetries: Set<Promise<void>>;
|
|
363
|
+
/** Listeners following the jobs this manager processes */
|
|
364
|
+
protected fListeners: Set<QueueTypes.JobListener>;
|
|
365
|
+
/**
|
|
366
|
+
* Whether consumers have been started.
|
|
367
|
+
*
|
|
368
|
+
* @returns {boolean} True once {@link QueueManager.start} ran
|
|
369
|
+
*/
|
|
370
|
+
get started(): boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Currently configured settings.
|
|
373
|
+
*
|
|
374
|
+
* @returns {Required<QueueTypes.Defaults>} A copy of the active settings
|
|
375
|
+
*/
|
|
376
|
+
get defaults(): Required<QueueTypes.Defaults>;
|
|
377
|
+
/**
|
|
378
|
+
* Sets manager-wide settings. Calling it repeatedly merges into the existing
|
|
379
|
+
* ones, and settings passed per job or per handler always win.
|
|
380
|
+
*
|
|
381
|
+
* @param {QueueTypes.Defaults} defaults - Settings to apply
|
|
382
|
+
* @returns {void}
|
|
383
|
+
*/
|
|
384
|
+
configure(defaults: QueueTypes.Defaults): void;
|
|
385
|
+
/**
|
|
386
|
+
* Mounts a strategy under a name. Every other call refers to it by that name,
|
|
387
|
+
* so a single application can talk to several brokers at once.
|
|
388
|
+
*
|
|
389
|
+
* The strategy is resolved through the container, connects on first use, and
|
|
390
|
+
* starts consuming right away when the manager is already running.
|
|
391
|
+
*
|
|
392
|
+
* @template T - Strategy being mounted
|
|
393
|
+
* @param {QueueTypes.Mount<T>} params - Mount name, strategy class and its init options
|
|
394
|
+
* @returns {Promise<void>} Resolves once the strategy is mounted
|
|
395
|
+
*/
|
|
396
|
+
mount<T extends QueueStrategy<unknown>>({ name, strategy, initOptions }: QueueTypes.Mount<T>): Promise<void>;
|
|
397
|
+
/**
|
|
398
|
+
* Stops and closes a mounted strategy, and forgets it.
|
|
399
|
+
* Handlers registered for it stay registered, so mounting it again resumes them.
|
|
400
|
+
*
|
|
401
|
+
* @param {string} [name] - Mount name, defaults to `default`
|
|
402
|
+
* @returns {Promise<void>} Resolves once the strategy is closed
|
|
403
|
+
*/
|
|
404
|
+
unmount(name?: string): Promise<void>;
|
|
405
|
+
/**
|
|
406
|
+
* Returns a mounted strategy, for the rare case a transport-specific API is needed.
|
|
407
|
+
*
|
|
408
|
+
* @param {string} [name] - Mount name, defaults to `default`
|
|
409
|
+
* @returns {QueueStrategy<unknown> | undefined} The strategy, or undefined when nothing is mounted under that name
|
|
410
|
+
*/
|
|
411
|
+
getStrategy(name?: string): QueueStrategy<unknown> | undefined;
|
|
412
|
+
/**
|
|
413
|
+
* Adds a single job to a queue.
|
|
414
|
+
*
|
|
415
|
+
* @template TQueue - Queue the job is added to
|
|
416
|
+
* @template TJob - Name of the job
|
|
417
|
+
* @param {QueueTypes.AddRequest<TQueue, TJob>} request - Queue, job name, payload and per-job options
|
|
418
|
+
* @returns {Promise<QueueTypes.JobRef>} Reference to the published job
|
|
419
|
+
* @throws {QueueError} When no strategy is mounted under the requested name, or the job cannot be published
|
|
420
|
+
*/
|
|
421
|
+
add<TQueue extends QueueTypes.QueueName, TJob extends QueueTypes.JobName<TQueue>>(request: QueueTypes.AddRequest<TQueue, TJob>): Promise<QueueTypes.JobRef>;
|
|
422
|
+
/**
|
|
423
|
+
* Adds many jobs of the same kind to a queue, using the transport's batch API
|
|
424
|
+
* when it has one.
|
|
425
|
+
*
|
|
426
|
+
* @template TQueue - Queue the jobs are added to
|
|
427
|
+
* @template TJob - Name of the jobs
|
|
428
|
+
* @param {QueueTypes.AddManyRequest<TQueue, TJob>} request - Queue, job name, payloads and per-job options
|
|
429
|
+
* @returns {Promise<QueueTypes.JobRef[]>} References to the published jobs, in the same order
|
|
430
|
+
* @throws {QueueError} When no strategy is mounted under the requested name, or the jobs cannot be published
|
|
431
|
+
*/
|
|
432
|
+
addMany<TQueue extends QueueTypes.QueueName, TJob extends QueueTypes.JobName<TQueue>>(request: QueueTypes.AddManyRequest<TQueue, TJob>): Promise<QueueTypes.JobRef[]>;
|
|
433
|
+
/**
|
|
434
|
+
* Registers a handler for a single job, or for every job the queue has no
|
|
435
|
+
* other handler for when registered under `*`. The decorators call this, and so
|
|
436
|
+
* can application code building its consumers dynamically.
|
|
437
|
+
*
|
|
438
|
+
* When the manager is already running, the queue starts being consumed right away.
|
|
439
|
+
*
|
|
440
|
+
* @param {QueueTypes.Registration} registration - Queue, job name, handler and its options
|
|
441
|
+
* @returns {void}
|
|
442
|
+
* @throws {QueueError} When a handler for the same job is already registered
|
|
443
|
+
*/
|
|
444
|
+
registerConsumer(registration: QueueTypes.Registration): void;
|
|
445
|
+
/**
|
|
446
|
+
* Registers a lifecycle hook for a queue.
|
|
447
|
+
*
|
|
448
|
+
* @param {'completed' | 'failed'} event - Event to listen for
|
|
449
|
+
* @param {QueueTypes.HookRegistration} registration - Queue, optional job filter and the hook itself
|
|
450
|
+
* @returns {void}
|
|
451
|
+
*/
|
|
452
|
+
registerHook(event: 'completed' | 'failed', registration: QueueTypes.HookRegistration): void;
|
|
453
|
+
/**
|
|
454
|
+
* Removes a registered handler. The queue stops being consumed once its last
|
|
455
|
+
* handler is gone.
|
|
456
|
+
*
|
|
457
|
+
* @param {Pick<QueueTypes.Registration, 'strategy' | 'queue' | 'job'>} registration - Handler to remove
|
|
458
|
+
* @returns {void}
|
|
459
|
+
*/
|
|
460
|
+
unregisterConsumer(registration: Pick<QueueTypes.Registration, 'strategy' | 'queue' | 'job'>): void;
|
|
461
|
+
/**
|
|
462
|
+
* Removes a registered lifecycle hook.
|
|
463
|
+
*
|
|
464
|
+
* @param {'completed' | 'failed'} event - Event the hook listens for
|
|
465
|
+
* @param {QueueTypes.HookRegistration} registration - The very registration that was registered
|
|
466
|
+
* @returns {void}
|
|
467
|
+
*/
|
|
468
|
+
unregisterHook(event: 'completed' | 'failed', registration: QueueTypes.HookRegistration): void;
|
|
469
|
+
/**
|
|
470
|
+
* Connects every mounted strategy and starts consuming every queue that has
|
|
471
|
+
* a handler. Safe to call more than once, queues already running are left alone.
|
|
472
|
+
*
|
|
473
|
+
* @returns {Promise<void>} Resolves once every consumer is running
|
|
474
|
+
*/
|
|
475
|
+
start(): Promise<void>;
|
|
476
|
+
/**
|
|
477
|
+
* Stops every consumer while keeping the connections open, so the application
|
|
478
|
+
* can still publish. In-flight jobs are awaited.
|
|
479
|
+
*
|
|
480
|
+
* @returns {Promise<void>} Resolves once every consumer is stopped
|
|
481
|
+
*/
|
|
482
|
+
stop(): Promise<void>;
|
|
483
|
+
/**
|
|
484
|
+
* Stops every consumer and closes every connection.
|
|
485
|
+
*
|
|
486
|
+
* @returns {Promise<void>} Resolves once everything is closed
|
|
487
|
+
*/
|
|
488
|
+
close(): Promise<void>;
|
|
489
|
+
/**
|
|
490
|
+
* Waits for the work the manager scheduled in the background: starting or
|
|
491
|
+
* stopping consumers, and retries waiting for their backoff to elapse.
|
|
492
|
+
*
|
|
493
|
+
* @returns {Promise<void>} Resolves once nothing is pending
|
|
494
|
+
*/
|
|
495
|
+
drain(): Promise<void>;
|
|
496
|
+
/**
|
|
497
|
+
* Reads live counters of a queue straight from the transport.
|
|
498
|
+
*
|
|
499
|
+
* @param {object} params - Queue to read and the strategy to read it from
|
|
500
|
+
* @param {string} params.queue - Queue to read
|
|
501
|
+
* @param {string} [params.strategy] - Mount name, defaults to `default`
|
|
502
|
+
* @returns {Promise<QueueTypes.QueueStats>} The counters the transport reports, empty when it reports none
|
|
503
|
+
*/
|
|
504
|
+
stats({ queue, strategy }: {
|
|
505
|
+
queue: string;
|
|
506
|
+
strategy?: string;
|
|
507
|
+
}): Promise<QueueTypes.QueueStats>;
|
|
508
|
+
/**
|
|
509
|
+
* Follows every job this manager finishes, as it finishes it.
|
|
510
|
+
*
|
|
511
|
+
* The listener is called with the same event that goes into the inspection
|
|
512
|
+
* buffer, right after the job settled, so a listener sees a queue live instead
|
|
513
|
+
* of polling it. A listener that throws is reported and kept.
|
|
514
|
+
*
|
|
515
|
+
* @param {QueueTypes.JobListener} listener - Called once per processed job
|
|
516
|
+
* @returns {() => void} Removes the listener again
|
|
517
|
+
*/
|
|
518
|
+
subscribe(listener: QueueTypes.JobListener): () => void;
|
|
519
|
+
/**
|
|
520
|
+
* Shows what a queue is holding, without consuming any of it.
|
|
521
|
+
*
|
|
522
|
+
* Only transports that can be read without side effects support this, which
|
|
523
|
+
* they report as the `peek` capability. Everything else returns nothing rather
|
|
524
|
+
* than perturbing the queue: taking delivery of a message to look at it would
|
|
525
|
+
* change delivery counts and compete with the running consumer.
|
|
526
|
+
*
|
|
527
|
+
* @param {object} params - Queue to look at and how much of it to read
|
|
528
|
+
* @param {string} params.queue - Queue to look at
|
|
529
|
+
* @param {string} [params.strategy] - Mount name, defaults to `default`
|
|
530
|
+
* @param {number} [params.limit] - How many messages to read, defaults to 20
|
|
531
|
+
* @param {QueueTypes.PeekState[]} [params.states] - States to read, defaults to waiting, delayed and failed
|
|
532
|
+
* @returns {Promise<QueueTypes.PeekedJob[]>} The messages found, with their payloads rendered
|
|
533
|
+
* @throws {QueueError} When the transport fails to answer
|
|
534
|
+
*/
|
|
535
|
+
peek({ queue, strategy, limit, states }: {
|
|
536
|
+
queue: string;
|
|
537
|
+
strategy?: string;
|
|
538
|
+
limit?: number;
|
|
539
|
+
states?: QueueTypes.PeekState[];
|
|
540
|
+
}): Promise<QueueTypes.PeekedJob[]>;
|
|
541
|
+
/**
|
|
542
|
+
* Describes what the module currently holds: mounted strategies, registered
|
|
543
|
+
* handlers, per-queue counters and the last processed jobs. Used by the devtools.
|
|
544
|
+
*
|
|
545
|
+
* @returns {QueueTypes.Snapshot} The current state of the queue module
|
|
546
|
+
*/
|
|
547
|
+
inspect(): QueueTypes.Snapshot;
|
|
548
|
+
/**
|
|
549
|
+
* Processes a single job: routes it to its handler, validates the payload,
|
|
550
|
+
* enforces the timeout, runs the lifecycle hooks and applies the retry policy.
|
|
551
|
+
*
|
|
552
|
+
* The handler registered for the job name wins, and a handler registered under
|
|
553
|
+
* `*` picks up whatever is left.
|
|
554
|
+
*
|
|
555
|
+
* Rejecting tells the strategy the job failed for good, so it can dead-letter it.
|
|
556
|
+
*
|
|
557
|
+
* @param {string} strategy - Mount name the job came from
|
|
558
|
+
* @param {string} queue - Queue the job came from
|
|
559
|
+
* @param {QueueTypes.IncomingJob} incoming - The job as received from the transport
|
|
560
|
+
* @returns {Promise<void>} Resolves when the job may be acknowledged
|
|
561
|
+
* @throws {Error} When the job failed and the transport has to deal with it
|
|
562
|
+
*/
|
|
563
|
+
protected process(strategy: string, queue: string, incoming: QueueTypes.IncomingJob): Promise<void>;
|
|
564
|
+
/**
|
|
565
|
+
* Does the work {@link QueueManager.process} traces.
|
|
566
|
+
*
|
|
567
|
+
* @param {string} strategy - Mount name the job came from
|
|
568
|
+
* @param {string} queue - Queue the job came from
|
|
569
|
+
* @param {QueueTypes.IncomingJob} incoming - The job as received from the transport
|
|
570
|
+
* @returns {Promise<void>} Resolves when the job may be acknowledged
|
|
571
|
+
* @throws {Error} When the job failed and the transport has to deal with it
|
|
572
|
+
*/
|
|
573
|
+
protected processJob(strategy: string, queue: string, incoming: QueueTypes.IncomingJob): Promise<void>;
|
|
574
|
+
/**
|
|
575
|
+
* Applies the failure policy of a job: hooks first, then either a retry the
|
|
576
|
+
* manager schedules itself, or a rejection handing the job back to the transport.
|
|
577
|
+
*
|
|
578
|
+
* @param {Error} error - Error the attempt failed with
|
|
579
|
+
* @param {QueueTypes.Registration} registration - Handler that failed
|
|
580
|
+
* @param {QueueTypes.JobContext} context - Context of the failed attempt
|
|
581
|
+
* @param {number} duration - How long the attempt took, in milliseconds
|
|
582
|
+
* @returns {Promise<void>} Resolves once a retry has been scheduled
|
|
583
|
+
* @throws {Error} The original error, when the transport has to deal with the failure
|
|
584
|
+
*/
|
|
585
|
+
protected handleFailure(error: Error, registration: QueueTypes.Registration, context: QueueTypes.JobContext, duration: number): Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Publishes the job again for its next attempt, waiting for the backoff first.
|
|
588
|
+
*
|
|
589
|
+
* The wait is handed to the transport when it can delay jobs, and kept on a
|
|
590
|
+
* timer otherwise, so the handler slot is released immediately either way.
|
|
591
|
+
*
|
|
592
|
+
* @param {QueueTypes.Registration} registration - Handler that failed
|
|
593
|
+
* @param {QueueTypes.JobContext} context - Context of the failed attempt
|
|
594
|
+
* @param {Error} error - Error the attempt failed with, reported when the retry cannot be published
|
|
595
|
+
* @returns {Promise<void>} Resolves once the retry exists, or once it has been scheduled on a timer
|
|
596
|
+
* @throws {Error} When the retry could be published right away and the transport refused it
|
|
597
|
+
*/
|
|
598
|
+
protected scheduleRetry(registration: QueueTypes.Registration, context: QueueTypes.JobContext, error: Error): Promise<void>;
|
|
599
|
+
/**
|
|
600
|
+
* Runs a handler, failing the attempt when it outlives its timeout.
|
|
601
|
+
* A timed out handler is not interrupted, it is only stopped being waited for.
|
|
602
|
+
*
|
|
603
|
+
* @param {QueueTypes.Registration} registration - Handler to run
|
|
604
|
+
* @param {QueueTypes.JobContext} context - Context of the attempt
|
|
605
|
+
* @returns {Promise<void>} Resolves once the handler returned
|
|
606
|
+
* @throws {QueueError} When the handler outlives its timeout
|
|
607
|
+
*/
|
|
608
|
+
protected runHandler(registration: QueueTypes.Registration, context: QueueTypes.JobContext): Promise<void>;
|
|
609
|
+
/**
|
|
610
|
+
* Validates a payload against the handler's schema, when it declares one.
|
|
611
|
+
*
|
|
612
|
+
* @param {QueueTypes.Registration} registration - Handler the payload is meant for
|
|
613
|
+
* @param {unknown} payload - Payload as received from the transport
|
|
614
|
+
* @param {string} job - Name of the job being processed, which a wildcard handler does not know upfront
|
|
615
|
+
* @returns {Promise<unknown>} The validated payload, as returned by the schema
|
|
616
|
+
* @throws {QueueError} When the payload does not match the schema, or no validation provider is bound
|
|
617
|
+
*/
|
|
618
|
+
protected validate(registration: QueueTypes.Registration, payload: unknown, job: string): Promise<unknown>;
|
|
619
|
+
/**
|
|
620
|
+
* Runs the hooks registered for a queue. A hook filtered by job name runs for
|
|
621
|
+
* that job only, unless the filter is `*`. A throwing hook is logged and never
|
|
622
|
+
* changes the outcome of the job.
|
|
623
|
+
*
|
|
624
|
+
* @param {'completed' | 'failed'} event - Event being reported
|
|
625
|
+
* @param {QueueTypes.Registration} registration - Handler the event belongs to
|
|
626
|
+
* @param {QueueTypes.JobContext} context - Context of the attempt
|
|
627
|
+
* @param {Error} [error] - Error of the attempt, for the `failed` event
|
|
628
|
+
* @returns {Promise<void>} Resolves once every hook settled
|
|
629
|
+
*/
|
|
630
|
+
protected runHooks(event: 'completed' | 'failed', registration: QueueTypes.Registration, context: QueueTypes.JobContext, error?: Error): Promise<void>;
|
|
631
|
+
/**
|
|
632
|
+
* Connects a mounted strategy and starts consuming every queue it has handlers for.
|
|
633
|
+
* Failures are logged and leave the other mounts untouched.
|
|
634
|
+
*
|
|
635
|
+
* @param {string} name - Mount name
|
|
636
|
+
* @returns {Promise<void>} Resolves once the mount is running
|
|
637
|
+
*/
|
|
638
|
+
protected startMount(name: string): Promise<void>;
|
|
639
|
+
/**
|
|
640
|
+
* Starts consuming a single queue, unless it is already being consumed.
|
|
641
|
+
*
|
|
642
|
+
* @param {string} strategy - Mount name
|
|
643
|
+
* @param {string} queue - Queue to consume
|
|
644
|
+
* @returns {Promise<void>} Resolves once the consumer is running
|
|
645
|
+
*/
|
|
646
|
+
protected startQueue(strategy: string, queue: string): Promise<void>;
|
|
647
|
+
/**
|
|
648
|
+
* Starts consuming a queue at a given concurrency and records the handle.
|
|
649
|
+
*
|
|
650
|
+
* @param {QueueTypes.MountedStrategy} mount - Mount the queue lives on
|
|
651
|
+
* @param {string} queue - Queue to consume
|
|
652
|
+
* @param {number} concurrency - How many jobs the transport may hand over at once
|
|
653
|
+
* @returns {Promise<void>} Resolves once the transport is delivering
|
|
654
|
+
* @throws {Error} When the strategy cannot start consuming
|
|
655
|
+
*/
|
|
656
|
+
private consumeQueue;
|
|
657
|
+
/**
|
|
658
|
+
* Stops every consumer of a mount.
|
|
659
|
+
*
|
|
660
|
+
* @param {string} strategy - Mount name
|
|
661
|
+
* @returns {Promise<void>} Resolves once every consumer is stopped
|
|
662
|
+
*/
|
|
663
|
+
protected stopConsumers(strategy: string): Promise<void>;
|
|
664
|
+
/**
|
|
665
|
+
* Stops the consumer of a single queue, waiting for its in-flight jobs.
|
|
666
|
+
*
|
|
667
|
+
* @param {string} strategy - Mount name
|
|
668
|
+
* @param {string} queue - Queue whose consumer is stopped
|
|
669
|
+
* @returns {Promise<void>} Resolves once the consumer is stopped
|
|
670
|
+
*/
|
|
671
|
+
protected stopQueue(strategy: string, queue: string): Promise<void>;
|
|
672
|
+
/**
|
|
673
|
+
* Closes a strategy, keeping a failure from breaking a shutdown sequence.
|
|
674
|
+
*
|
|
675
|
+
* @param {QueueTypes.MountedStrategy} mount - Mount to close
|
|
676
|
+
* @returns {Promise<void>} Resolves once the strategy is closed
|
|
677
|
+
*/
|
|
678
|
+
protected closeStrategy(mount: QueueTypes.MountedStrategy<any>): Promise<void>;
|
|
679
|
+
/**
|
|
680
|
+
* Initializes a strategy once, reusing the same promise for every later call.
|
|
681
|
+
*
|
|
682
|
+
* @param {QueueTypes.MountedStrategy} mount - Mount to initialize
|
|
683
|
+
* @returns {Promise<void>} Resolves once the strategy is ready
|
|
684
|
+
* @throws {QueueError} When the strategy cannot be initialized
|
|
685
|
+
*/
|
|
686
|
+
protected ensureReady(mount: QueueTypes.MountedStrategy<any>): Promise<void>;
|
|
687
|
+
/**
|
|
688
|
+
* Resolves a mount by name and makes sure it is connected.
|
|
689
|
+
*
|
|
690
|
+
* @param {string} [name] - Mount name, defaults to `default`
|
|
691
|
+
* @param {string} operation - Operation asking for the mount, reported in the error
|
|
692
|
+
* @returns {Promise<QueueTypes.MountedStrategy>} The ready mount
|
|
693
|
+
* @throws {QueueError} When nothing is mounted under that name, or it cannot connect
|
|
694
|
+
*/
|
|
695
|
+
protected resolveMount(name: string | undefined, operation: string): Promise<QueueTypes.MountedStrategy<any>>;
|
|
696
|
+
/**
|
|
697
|
+
* Builds the transport-facing shape of a job, adding the headers the module
|
|
698
|
+
* needs to route and retry it.
|
|
699
|
+
*
|
|
700
|
+
* @param {string} queue - Queue the job goes to
|
|
701
|
+
* @param {string} job - Name of the job
|
|
702
|
+
* @param {unknown} payload - Payload of the job
|
|
703
|
+
* @param {QueueTypes.JobOptions} [options] - Per-job options
|
|
704
|
+
* @returns {QueueTypes.PublishRequest} The job as a strategy expects it
|
|
705
|
+
*/
|
|
706
|
+
protected createPublishRequest(queue: string, job: string, payload: unknown, options?: QueueTypes.JobOptions): QueueTypes.PublishRequest;
|
|
707
|
+
/**
|
|
708
|
+
* Builds the context a handler and its hooks receive.
|
|
709
|
+
*
|
|
710
|
+
* @param {string} strategy - Mount name the job came from
|
|
711
|
+
* @param {string} queue - Queue the job came from
|
|
712
|
+
* @param {QueueTypes.IncomingJob} incoming - The job as received from the transport
|
|
713
|
+
* @param {number} attempts - Total attempts this job may take
|
|
714
|
+
* @returns {QueueTypes.JobContext} The context of this attempt
|
|
715
|
+
*/
|
|
716
|
+
protected createContext(strategy: string, queue: string, incoming: QueueTypes.IncomingJob, attempts: number): QueueTypes.JobContext;
|
|
717
|
+
/**
|
|
718
|
+
* Returns the counters of a queue, creating them on first use.
|
|
719
|
+
*
|
|
720
|
+
* @param {string} strategy - Mount name
|
|
721
|
+
* @param {string} queue - Queue name
|
|
722
|
+
* @returns {QueueTypes.QueueMetrics} The mutable counters of that queue
|
|
723
|
+
*/
|
|
724
|
+
protected metricsFor(strategy: string, queue: string): QueueTypes.QueueMetrics;
|
|
725
|
+
/**
|
|
726
|
+
* Appends a processed job to the inspection buffer, dropping the oldest entry
|
|
727
|
+
* once the buffer is full.
|
|
728
|
+
*
|
|
729
|
+
* The payload and headers of a failure are kept only while `capturePayloads`
|
|
730
|
+
* is on, and never for a job that completed: that is where the volume is, and
|
|
731
|
+
* a job that worked has nothing to diagnose.
|
|
732
|
+
*
|
|
733
|
+
* @param {Omit<QueueTypes.JobEvent, 'at'>} event - The processed job
|
|
734
|
+
* @param {unknown} [payload] - Payload of the attempt, kept when capturing is on
|
|
735
|
+
* @param {Record<string, string>} [headers] - Headers of the attempt, kept when capturing is on
|
|
736
|
+
* @returns {void}
|
|
737
|
+
*/
|
|
738
|
+
protected record(event: Omit<QueueTypes.JobEvent, 'at'>, payload?: unknown, headers?: Record<string, string>): void;
|
|
739
|
+
/**
|
|
740
|
+
* Describes an error for the inspection buffer: its name, message and a capped
|
|
741
|
+
* stack, plus what this module knows about it when it raised the error itself.
|
|
742
|
+
*
|
|
743
|
+
* @param {Error} error - Error the attempt failed with
|
|
744
|
+
* @returns {QueueTypes.JobFailure} The failure, ready to be inspected
|
|
745
|
+
*/
|
|
746
|
+
protected describeFailure(error: Error): QueueTypes.JobFailure;
|
|
747
|
+
/**
|
|
748
|
+
* Reports the state of a mount for the devtools.
|
|
749
|
+
*
|
|
750
|
+
* @param {QueueTypes.MountedStrategy} mount - Mount to describe
|
|
751
|
+
* @returns {QueueTypes.StrategyStatus} What the mount is currently doing
|
|
752
|
+
*/
|
|
753
|
+
protected statusOf(mount: QueueTypes.MountedStrategy<any>): QueueTypes.StrategyStatus;
|
|
754
|
+
/**
|
|
755
|
+
* Runs a piece of lifecycle work after everything scheduled before it, so
|
|
756
|
+
* consumers are never started or stopped concurrently.
|
|
757
|
+
*
|
|
758
|
+
* @param {() => Promise<void>} task - Work to run
|
|
759
|
+
* @returns {Promise<void>} Resolves once this task ran
|
|
760
|
+
*/
|
|
761
|
+
protected enqueue(task: () => Promise<void>): Promise<void>;
|
|
762
|
+
/**
|
|
763
|
+
* Key a handler is registered under.
|
|
764
|
+
*
|
|
765
|
+
* @param {string} strategy - Mount name
|
|
766
|
+
* @param {string} queue - Queue name
|
|
767
|
+
* @param {string} job - Job name
|
|
768
|
+
* @returns {string} The registration key
|
|
769
|
+
*/
|
|
770
|
+
protected consumerKey(strategy: string, queue: string, job: string): string;
|
|
771
|
+
/**
|
|
772
|
+
* Key a queue is tracked under.
|
|
773
|
+
*
|
|
774
|
+
* @param {string} strategy - Mount name
|
|
775
|
+
* @param {string} queue - Queue name
|
|
776
|
+
* @returns {string} The queue key
|
|
777
|
+
*/
|
|
778
|
+
protected queueKey(strategy: string, queue: string): string;
|
|
779
|
+
/**
|
|
780
|
+
* Starts the consumers once the container is initialized, so every handler
|
|
781
|
+
* registered by a decorator is known before the first job is received.
|
|
782
|
+
*
|
|
783
|
+
* @returns {void}
|
|
784
|
+
*/
|
|
785
|
+
protected init(): void;
|
|
786
|
+
/**
|
|
787
|
+
* Closes every connection when the container is torn down.
|
|
788
|
+
*
|
|
789
|
+
* @returns {void}
|
|
790
|
+
*/
|
|
791
|
+
protected destroy(): void;
|
|
792
|
+
}
|
|
793
|
+
//#endregion
|
|
794
|
+
//#region src/Utils/Errors.d.ts
|
|
795
|
+
/**
|
|
796
|
+
* Turns any thrown value into a {@link QueueError}, leaving queue errors alone so
|
|
797
|
+
* their operation and `retryable` flag survive.
|
|
798
|
+
*
|
|
799
|
+
* @param error - The value that was thrown.
|
|
800
|
+
* @param message - Message of the resulting error.
|
|
801
|
+
* @param operation - Queue operation that failed.
|
|
802
|
+
* @param metadata - Additional non-sensitive context.
|
|
803
|
+
* @returns The error to throw.
|
|
804
|
+
*/
|
|
805
|
+
export declare function toQueueError(error: unknown, message: string, operation: string, metadata?: Record<string, unknown>): QueueError;
|
|
806
|
+
//#endregion
|
|
807
|
+
//#region src/Utils/Job.d.ts
|
|
808
|
+
/**
|
|
809
|
+
* Job name a handler registers under to receive every job of its queue that no
|
|
810
|
+
* other handler claims.
|
|
811
|
+
*/
|
|
812
|
+
export declare const WILDCARD_JOB = "*";
|
|
813
|
+
/** Header carrying the job name across transports that have no native notion of one. */
|
|
814
|
+
export declare const JOB_HEADER = "x-job";
|
|
815
|
+
/** Header carrying the current attempt number. */
|
|
816
|
+
export declare const ATTEMPT_HEADER = "x-attempt";
|
|
817
|
+
/** Header carrying the total number of attempts the publisher asked for. */
|
|
818
|
+
export declare const ATTEMPTS_HEADER = "x-attempts";
|
|
819
|
+
/** Header carrying the partition or routing key a job was published with. */
|
|
820
|
+
export declare const KEY_HEADER = "x-key";
|
|
821
|
+
/** Header carrying the priority a job was published with. */
|
|
822
|
+
export declare const PRIORITY_HEADER = "x-priority";
|
|
823
|
+
/**
|
|
824
|
+
* Most attempts a job may ever take.
|
|
825
|
+
*
|
|
826
|
+
* On transports that do not retry natively the budget is read off the wire, so a
|
|
827
|
+
* producer could otherwise ask for an arbitrarily large one and turn a single
|
|
828
|
+
* poison message into an unbounded republish loop.
|
|
829
|
+
*/
|
|
830
|
+
export declare const MAX_ATTEMPTS = 50;
|
|
831
|
+
/**
|
|
832
|
+
* Longest a retry may be held back, one day.
|
|
833
|
+
*
|
|
834
|
+
* An exponential backoff over a large attempt count overflows to `Infinity`,
|
|
835
|
+
* which `setTimeout` clamps to one millisecond: the backoff meant to slow
|
|
836
|
+
* retries down would make them as fast as the runtime allows.
|
|
837
|
+
*/
|
|
838
|
+
export declare const MAX_BACKOFF_MS = 86400000;
|
|
839
|
+
/**
|
|
840
|
+
* Reads a positive integer from a raw header value.
|
|
841
|
+
*
|
|
842
|
+
* @param raw - Header value as received from the transport, in any shape.
|
|
843
|
+
* @param fallback - Value returned when the header is absent or unusable.
|
|
844
|
+
* @param max - Largest value accepted, so a value off the wire cannot be unbounded.
|
|
845
|
+
* @returns The parsed integer, or the fallback.
|
|
846
|
+
*/
|
|
847
|
+
export declare function readNumericHeader(raw: unknown, fallback: number, max?: number): number;
|
|
848
|
+
/**
|
|
849
|
+
* Normalizes transport headers into plain strings, so handlers never have to deal
|
|
850
|
+
* with buffers or numbers coming from the wire.
|
|
851
|
+
*
|
|
852
|
+
* @param headers - Raw headers as received from the transport.
|
|
853
|
+
* @returns Headers with string values only.
|
|
854
|
+
*/
|
|
855
|
+
export declare function normalizeHeaders(headers: Record<string, unknown> | undefined | null): Record<string, string>;
|
|
856
|
+
/**
|
|
857
|
+
* Computes how long to wait before the next attempt of a job.
|
|
858
|
+
*
|
|
859
|
+
* @param backoff - Backoff policy, a number being a fixed delay in milliseconds.
|
|
860
|
+
* @param attempt - Attempt that just failed, starting at 1.
|
|
861
|
+
* @returns Delay in milliseconds, zero when no backoff is configured and never above {@link MAX_BACKOFF_MS}.
|
|
862
|
+
*/
|
|
863
|
+
export declare function resolveBackoff(backoff: QueueTypes.Backoff | undefined, attempt: number): number;
|
|
864
|
+
/**
|
|
865
|
+
* Serializes a payload for transports that only carry bytes.
|
|
866
|
+
*
|
|
867
|
+
* @param payload - Payload to serialize.
|
|
868
|
+
* @returns The payload as a UTF-8 JSON buffer.
|
|
869
|
+
* @throws {QueueError} When the payload cannot be serialized.
|
|
870
|
+
*/
|
|
871
|
+
export declare function encodePayload(payload: unknown): Buffer;
|
|
872
|
+
/**
|
|
873
|
+
* Deserializes a payload received from a transport that only carries bytes.
|
|
874
|
+
* Content that is not JSON is returned as text, so foreign producers do not
|
|
875
|
+
* break the consumer.
|
|
876
|
+
*
|
|
877
|
+
* @param content - Raw bytes received from the transport.
|
|
878
|
+
* @returns The parsed payload, or the raw text when it is not JSON.
|
|
879
|
+
*/
|
|
880
|
+
export declare function decodePayload(content: Uint8Array | Buffer | string | null | undefined): unknown;
|
|
881
|
+
/**
|
|
882
|
+
* Generates an id for transports that do not assign one themselves.
|
|
883
|
+
*
|
|
884
|
+
* @returns A unique job id.
|
|
885
|
+
*/
|
|
886
|
+
export declare function generateJobId(): string;
|
|
887
|
+
/**
|
|
888
|
+
* Waits for the given number of milliseconds.
|
|
889
|
+
*
|
|
890
|
+
* @param ms - Milliseconds to wait, values below one resolve immediately.
|
|
891
|
+
* @returns Resolves once the delay elapsed.
|
|
892
|
+
*/
|
|
893
|
+
export declare function delay(ms: number): Promise<void>;
|
|
894
|
+
/**
|
|
895
|
+
* Drops the keys whose value is undefined.
|
|
896
|
+
*
|
|
897
|
+
* Options objects are built by spreading whatever the caller set, which leaves
|
|
898
|
+
* own properties holding `undefined` behind. A library that merges options with
|
|
899
|
+
* `Object.assign` cannot tell those apart from a deliberate value, so they have
|
|
900
|
+
* to go before the object is handed over.
|
|
901
|
+
*
|
|
902
|
+
* @param source - Object to clean up.
|
|
903
|
+
* @returns A copy without the undefined entries.
|
|
904
|
+
*/
|
|
905
|
+
export declare function prune<T extends Record<string, unknown>>(source: T): T;
|
|
906
|
+
//#endregion
|
|
907
|
+
//#region src/Utils/Mount.d.ts
|
|
908
|
+
/**
|
|
909
|
+
* Type checks a single strategy mount and erases its options, so a list of
|
|
910
|
+
* mounts of different strategies stays checked.
|
|
911
|
+
*
|
|
912
|
+
* `QueueManager.mount()` infers the strategy from its argument and checks
|
|
913
|
+
* `initOptions` against it. A plain array in `QueuePlugin` options cannot do
|
|
914
|
+
* that, since there is no inference site per entry - this helper is that site.
|
|
915
|
+
*
|
|
916
|
+
* @param {QueueTypes.Mount<T>} mount - Mount name, strategy class and its init options
|
|
917
|
+
* @returns {QueueTypes.AnyMount} The very same mount, with its options type erased
|
|
918
|
+
*
|
|
919
|
+
* @example
|
|
920
|
+
* ```ts
|
|
921
|
+
* app.addPlugin(QueuePlugin, {
|
|
922
|
+
* strategies: [
|
|
923
|
+
* defineQueueStrategy({ strategy: RabbitMQStrategy, initOptions: { url: 'amqp://localhost' } }),
|
|
924
|
+
* defineQueueStrategy({
|
|
925
|
+
* name: 'events',
|
|
926
|
+
* strategy: KafkaStrategy,
|
|
927
|
+
* initOptions: { client: { brokers: ['localhost:9092'] }, groupId: 'workers' },
|
|
928
|
+
* }),
|
|
929
|
+
* ],
|
|
930
|
+
* });
|
|
931
|
+
* ```
|
|
932
|
+
*/
|
|
933
|
+
export declare function defineQueueStrategy<T extends QueueStrategy<unknown>>(mount: QueueTypes.Mount<T>): QueueTypes.AnyMount;
|
|
934
|
+
//#endregion
|
|
935
|
+
//#region src/Utils/Metadata.d.ts
|
|
936
|
+
/**
|
|
937
|
+
* Stores the options a `@Consumer()` class was declared with.
|
|
938
|
+
*
|
|
939
|
+
* @param prototype - Prototype of the decorated class.
|
|
940
|
+
* @param options - Options the class was declared with.
|
|
941
|
+
* @returns Nothing.
|
|
942
|
+
*/
|
|
943
|
+
export declare function setConsumerOptions(prototype: object, options: QueueTypes.ConsumerOptions): void;
|
|
944
|
+
/**
|
|
945
|
+
* Reads the options of the closest `@Consumer()` class in the prototype chain,
|
|
946
|
+
* so a handler declared on a base class still finds its queue.
|
|
947
|
+
*
|
|
948
|
+
* @param prototype - Prototype to start looking at.
|
|
949
|
+
* @returns The options, or undefined when no class in the chain is a consumer.
|
|
950
|
+
*/
|
|
951
|
+
export declare function getConsumerOptions(prototype: object | null): QueueTypes.ConsumerOptions | undefined;
|
|
952
|
+
//#endregion
|
|
953
|
+
export { QueueStrategy, QueueTypes };
|