@tsed/bullmq 7.47.1 → 7.49.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/README.md +116 -11
- package/jest.config.js +1 -1
- package/lib/cjs/BullMQModule.js +24 -9
- package/lib/cjs/BullMQModule.js.map +1 -1
- package/lib/cjs/decorators/JobController.js +10 -1
- package/lib/cjs/decorators/JobController.js.map +1 -1
- package/lib/cjs/dispatchers/JobDispatcher.js +35 -8
- package/lib/cjs/dispatchers/JobDispatcher.js.map +1 -1
- package/lib/cjs/dispatchers/JobDispatcherOptions.js +3 -0
- package/lib/cjs/dispatchers/JobDispatcherOptions.js.map +1 -0
- package/lib/cjs/dispatchers/index.js +1 -0
- package/lib/cjs/dispatchers/index.js.map +1 -1
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/BullMQModule.js +24 -9
- package/lib/esm/BullMQModule.js.map +1 -1
- package/lib/esm/decorators/JobController.js +8 -0
- package/lib/esm/decorators/JobController.js.map +1 -1
- package/lib/esm/dispatchers/JobDispatcher.js +35 -8
- package/lib/esm/dispatchers/JobDispatcher.js.map +1 -1
- package/lib/esm/dispatchers/JobDispatcherOptions.js +2 -0
- package/lib/esm/dispatchers/JobDispatcherOptions.js.map +1 -0
- package/lib/esm/dispatchers/index.js +1 -0
- package/lib/esm/dispatchers/index.js.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/config/config.d.ts +40 -1
- package/lib/types/contracts/JobMethods.d.ts +3 -2
- package/lib/types/decorators/JobController.d.ts +1 -0
- package/lib/types/dispatchers/JobDispatcher.d.ts +4 -0
- package/lib/types/dispatchers/JobDispatcherOptions.d.ts +4 -0
- package/lib/types/dispatchers/index.d.ts +1 -0
- package/lib/types/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/BullMQModule.spec.ts +295 -118
- package/src/BullMQModule.ts +35 -10
- package/src/config/config.ts +48 -3
- package/src/contracts/JobMethods.ts +4 -2
- package/src/decorators/JobController.spec.ts +44 -1
- package/src/decorators/JobController.ts +12 -0
- package/src/dispatchers/JobDispatcher.spec.ts +48 -14
- package/src/dispatchers/JobDispatcher.ts +44 -8
- package/src/dispatchers/JobDispatcherOptions.ts +4 -0
- package/src/dispatchers/index.ts +1 -0
- package/src/index.ts +1 -0
|
@@ -1,10 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ConnectionOptions, DefaultJobOptions, QueueOptions, WorkerOptions } from "bullmq";
|
|
2
2
|
export type BullMQConfig = {
|
|
3
|
+
/**
|
|
4
|
+
* Specify queue name's to create
|
|
5
|
+
*/
|
|
3
6
|
queues: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Default connection to use for queue's and worker's
|
|
9
|
+
*/
|
|
4
10
|
connection: ConnectionOptions;
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Use defaultQueueOptions instead. Will be removed in the next major release
|
|
13
|
+
*/
|
|
5
14
|
defaultJobOptions?: DefaultJobOptions;
|
|
15
|
+
/**
|
|
16
|
+
* Default queue options which are applied to every queue
|
|
17
|
+
*
|
|
18
|
+
* Can be extended/overridden by `queueOptions`
|
|
19
|
+
*/
|
|
20
|
+
defaultQueueOptions?: QueueOptions;
|
|
21
|
+
/**
|
|
22
|
+
* Specify additional queue options by queue name
|
|
23
|
+
*/
|
|
24
|
+
queueOptions?: Record<string, QueueOptions>;
|
|
25
|
+
/**
|
|
26
|
+
* Disable the creation of any worker.
|
|
27
|
+
*
|
|
28
|
+
* All other worker configuration will be ignored
|
|
29
|
+
*/
|
|
6
30
|
disableWorker?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Specify for which queues to start a worker for.
|
|
33
|
+
*
|
|
34
|
+
* Defaultly for every queue added in the `queues` parameter
|
|
35
|
+
*/
|
|
7
36
|
workerQueues?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Default worker options which are applied to every worker
|
|
39
|
+
*
|
|
40
|
+
* Can be extended/overridden by `workerOptions`
|
|
41
|
+
*/
|
|
42
|
+
defaultWorkerOptions?: WorkerOptions;
|
|
43
|
+
/**
|
|
44
|
+
* Specify additional worker options by queue name
|
|
45
|
+
*/
|
|
46
|
+
workerOptions?: Record<string, WorkerOptions>;
|
|
8
47
|
};
|
|
9
48
|
declare global {
|
|
10
49
|
namespace TsED {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { Job } from "bullmq";
|
|
2
|
+
export interface JobMethods<DataType = unknown, ReturnType = unknown> {
|
|
3
|
+
handle(payload: DataType, job: Job<DataType, ReturnType>): ReturnType | Promise<ReturnType>;
|
|
3
4
|
}
|
|
@@ -2,8 +2,12 @@ import { InjectorService } from "@tsed/di";
|
|
|
2
2
|
import { JobMethods } from "../contracts";
|
|
3
3
|
import { Type } from "@tsed/core";
|
|
4
4
|
import { Job as BullMQJob, JobsOptions } from "bullmq";
|
|
5
|
+
import type { JobDispatcherOptions } from "./JobDispatcherOptions";
|
|
5
6
|
export declare class JobDispatcher {
|
|
6
7
|
private readonly injector;
|
|
7
8
|
constructor(injector: InjectorService);
|
|
8
9
|
dispatch<T extends JobMethods>(job: Type<T>, payload?: Parameters<T["handle"]>[0], options?: JobsOptions): Promise<BullMQJob>;
|
|
10
|
+
dispatch<T = any>(job: JobDispatcherOptions, payload?: T, options?: JobsOptions): Promise<BullMQJob>;
|
|
11
|
+
dispatch<T = any>(job: string, payload?: T, options?: JobsOptions): Promise<BullMQJob>;
|
|
12
|
+
private resolveDispatchArgs;
|
|
9
13
|
}
|
package/lib/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/bullmq",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.49.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "BullMQ integration for Ts.ED",
|
|
6
6
|
"keywords": [
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"tslib": "2.5.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@tsed/common": "7.
|
|
33
|
-
"@tsed/core": "7.
|
|
34
|
-
"@tsed/di": "7.
|
|
32
|
+
"@tsed/common": "7.49.0",
|
|
33
|
+
"@tsed/core": "7.49.0",
|
|
34
|
+
"@tsed/di": "7.49.0",
|
|
35
35
|
"@tsed/eslint": "7.44.1",
|
|
36
|
-
"@tsed/schema": "7.
|
|
36
|
+
"@tsed/schema": "7.49.0",
|
|
37
37
|
"@tsed/typescript": "7.44.1",
|
|
38
38
|
"bullmq": "^4.12.3",
|
|
39
39
|
"eslint": "^8.12.0",
|
package/src/BullMQModule.spec.ts
CHANGED
|
@@ -1,42 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {PlatformTest} from "@tsed/common";
|
|
2
2
|
import {catchAsyncError} from "@tsed/core";
|
|
3
3
|
import {Queue, Worker} from "bullmq";
|
|
4
|
-
import {
|
|
4
|
+
import {anything, instance, mock, verify, when} from "ts-mockito";
|
|
5
5
|
|
|
6
6
|
import "./BullMQModule";
|
|
7
7
|
import {BullMQModule} from "./BullMQModule";
|
|
8
8
|
import {type BullMQConfig} from "./config/config";
|
|
9
9
|
import {JobMethods} from "./contracts";
|
|
10
|
-
import {JobController} from "./decorators";
|
|
10
|
+
import {FallbackJobController, JobController} from "./decorators";
|
|
11
11
|
import {JobDispatcher} from "./dispatchers";
|
|
12
12
|
|
|
13
|
+
const queueConstructorSpy = jest.fn();
|
|
14
|
+
const workerConstructorSpy = jest.fn();
|
|
15
|
+
|
|
13
16
|
jest.mock("bullmq", () => {
|
|
14
17
|
return {
|
|
15
18
|
Queue: class {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
constructor(name: string) {
|
|
19
|
-
this.name = name;
|
|
19
|
+
constructor(...args: any[]) {
|
|
20
|
+
queueConstructorSpy(...args);
|
|
20
21
|
}
|
|
21
22
|
close() {}
|
|
22
23
|
},
|
|
23
24
|
Worker: class {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
constructor(name: string) {
|
|
27
|
-
this.name = name;
|
|
25
|
+
constructor(...args: any[]) {
|
|
26
|
+
workerConstructorSpy(...args);
|
|
28
27
|
}
|
|
29
28
|
close() {}
|
|
30
29
|
}
|
|
31
30
|
};
|
|
32
31
|
});
|
|
33
32
|
|
|
34
|
-
const bullmq = {
|
|
35
|
-
queues: ["default", "foo", "bar"],
|
|
36
|
-
connection: {},
|
|
37
|
-
workerQueues: ["default", "foo"]
|
|
38
|
-
} as BullMQConfig;
|
|
39
|
-
|
|
40
33
|
@JobController("cron", "default", {
|
|
41
34
|
repeat: {
|
|
42
35
|
pattern: "* * * * *"
|
|
@@ -51,154 +44,338 @@ class RegularJob {
|
|
|
51
44
|
handle() {}
|
|
52
45
|
}
|
|
53
46
|
|
|
54
|
-
describe("
|
|
47
|
+
describe("BullMQModule", () => {
|
|
55
48
|
let dispatcher: JobDispatcher;
|
|
56
|
-
|
|
49
|
+
|
|
50
|
+
beforeEach(() => {
|
|
57
51
|
dispatcher = mock(JobDispatcher);
|
|
58
52
|
when(dispatcher.dispatch(CustomCronJob)).thenResolve();
|
|
59
|
-
|
|
60
|
-
await PlatformTest.create({
|
|
61
|
-
bullmq,
|
|
62
|
-
imports: [
|
|
63
|
-
{
|
|
64
|
-
token: JobDispatcher,
|
|
65
|
-
use: instance(dispatcher)
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
});
|
|
69
53
|
});
|
|
70
|
-
|
|
54
|
+
|
|
71
55
|
afterEach(PlatformTest.reset);
|
|
72
56
|
|
|
73
|
-
describe("
|
|
74
|
-
|
|
75
|
-
|
|
57
|
+
describe("configuration", () => {
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
queueConstructorSpy.mockClear();
|
|
60
|
+
workerConstructorSpy.mockClear();
|
|
76
61
|
});
|
|
77
|
-
});
|
|
78
62
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
63
|
+
describe("merges config correctly", () => {
|
|
64
|
+
beforeEach(async () => {
|
|
65
|
+
await PlatformTest.create({
|
|
66
|
+
bullmq: {
|
|
67
|
+
queues: ["default", "special"],
|
|
68
|
+
connection: {
|
|
69
|
+
connectionName: "defaultConnectionName"
|
|
70
|
+
},
|
|
71
|
+
defaultQueueOptions: {
|
|
72
|
+
defaultJobOptions: {
|
|
73
|
+
delay: 100
|
|
74
|
+
},
|
|
75
|
+
blockingConnection: true
|
|
76
|
+
},
|
|
77
|
+
queueOptions: {
|
|
78
|
+
special: {
|
|
79
|
+
connection: {
|
|
80
|
+
connectionName: "specialConnectionName"
|
|
81
|
+
},
|
|
82
|
+
defaultJobOptions: {
|
|
83
|
+
attempts: 9
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
defaultWorkerOptions: {
|
|
88
|
+
connection: {
|
|
89
|
+
connectTimeout: 123
|
|
90
|
+
},
|
|
91
|
+
concurrency: 50
|
|
92
|
+
},
|
|
93
|
+
workerOptions: {
|
|
94
|
+
special: {
|
|
95
|
+
concurrency: 1,
|
|
96
|
+
lockDuration: 2
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
imports: [
|
|
101
|
+
{
|
|
102
|
+
token: JobDispatcher,
|
|
103
|
+
use: instance(dispatcher)
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
});
|
|
82
108
|
|
|
83
|
-
|
|
84
|
-
|
|
109
|
+
it("queue", () => {
|
|
110
|
+
expect(queueConstructorSpy).toHaveBeenCalledTimes(2);
|
|
111
|
+
|
|
112
|
+
expect(queueConstructorSpy).toHaveBeenNthCalledWith(1, "default", {
|
|
113
|
+
connection: {
|
|
114
|
+
connectionName: "defaultConnectionName"
|
|
115
|
+
},
|
|
116
|
+
defaultJobOptions: {
|
|
117
|
+
delay: 100
|
|
118
|
+
},
|
|
119
|
+
blockingConnection: true
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(queueConstructorSpy).toHaveBeenNthCalledWith(2, "special", {
|
|
123
|
+
connection: {
|
|
124
|
+
connectionName: "specialConnectionName"
|
|
125
|
+
},
|
|
126
|
+
defaultJobOptions: {
|
|
127
|
+
attempts: 9,
|
|
128
|
+
delay: 100
|
|
129
|
+
},
|
|
130
|
+
blockingConnection: true
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("worker", () => {
|
|
135
|
+
expect(workerConstructorSpy).toHaveBeenCalledTimes(2);
|
|
136
|
+
|
|
137
|
+
expect(workerConstructorSpy).toHaveBeenNthCalledWith(1, "default", expect.any(Function), {
|
|
138
|
+
connection: {
|
|
139
|
+
connectTimeout: 123
|
|
140
|
+
},
|
|
141
|
+
concurrency: 50
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(workerConstructorSpy).toHaveBeenNthCalledWith(2, "special", expect.any(Function), {
|
|
145
|
+
connection: {
|
|
146
|
+
connectTimeout: 123
|
|
147
|
+
},
|
|
148
|
+
concurrency: 1,
|
|
149
|
+
lockDuration: 2
|
|
150
|
+
});
|
|
151
|
+
});
|
|
85
152
|
});
|
|
86
153
|
|
|
87
|
-
|
|
88
|
-
const
|
|
154
|
+
describe("disableWorker", () => {
|
|
155
|
+
const config = {
|
|
156
|
+
queues: ["default", "foo", "bar"],
|
|
157
|
+
connection: {},
|
|
158
|
+
disableWorker: true
|
|
159
|
+
} as BullMQConfig;
|
|
160
|
+
|
|
161
|
+
beforeEach(async () => {
|
|
162
|
+
await PlatformTest.create({
|
|
163
|
+
bullmq: config,
|
|
164
|
+
imports: [
|
|
165
|
+
{
|
|
166
|
+
token: JobDispatcher,
|
|
167
|
+
use: instance(dispatcher)
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
});
|
|
89
172
|
|
|
90
|
-
|
|
91
|
-
|
|
173
|
+
it("should not create any workers", () => {
|
|
174
|
+
expect(workerConstructorSpy).toHaveBeenCalledTimes(0);
|
|
175
|
+
});
|
|
92
176
|
});
|
|
93
177
|
|
|
94
|
-
|
|
95
|
-
|
|
178
|
+
describe("without", () => {
|
|
179
|
+
it("skips initialization", async () => {
|
|
180
|
+
await PlatformTest.create({
|
|
181
|
+
imports: [
|
|
182
|
+
{
|
|
183
|
+
token: JobDispatcher,
|
|
184
|
+
use: instance(dispatcher)
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(queueConstructorSpy).not.toHaveBeenCalled();
|
|
190
|
+
verify(dispatcher.dispatch(anything())).never();
|
|
191
|
+
});
|
|
96
192
|
});
|
|
97
193
|
});
|
|
98
194
|
|
|
99
|
-
describe("
|
|
100
|
-
|
|
101
|
-
|
|
195
|
+
describe("functionality", () => {
|
|
196
|
+
const config = {
|
|
197
|
+
queues: ["default", "foo", "bar"],
|
|
198
|
+
connection: {},
|
|
199
|
+
workerQueues: ["default", "foo"]
|
|
200
|
+
} as BullMQConfig;
|
|
201
|
+
|
|
202
|
+
beforeEach(async () => {
|
|
203
|
+
await PlatformTest.create({
|
|
204
|
+
bullmq: config,
|
|
205
|
+
imports: [
|
|
206
|
+
{
|
|
207
|
+
token: JobDispatcher,
|
|
208
|
+
use: instance(dispatcher)
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
});
|
|
212
|
+
});
|
|
102
213
|
|
|
103
|
-
|
|
104
|
-
|
|
214
|
+
describe("cronjobs", () => {
|
|
215
|
+
it("should dispatch cron jobs automatically", () => {
|
|
216
|
+
verify(dispatcher.dispatch(CustomCronJob)).once();
|
|
217
|
+
});
|
|
105
218
|
});
|
|
106
219
|
|
|
107
|
-
|
|
108
|
-
|
|
220
|
+
describe("queues", () => {
|
|
221
|
+
it("should get default", () => {
|
|
222
|
+
const instance = PlatformTest.get<Queue>("bullmq.queue.default");
|
|
109
223
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
224
|
+
expect(instance).toBeInstanceOf(Queue);
|
|
225
|
+
});
|
|
113
226
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
227
|
+
it.each(config.queues)("should register queue(%s)", (queue) => {
|
|
228
|
+
const instance = PlatformTest.get<Queue>(`bullmq.queue.${queue}`);
|
|
229
|
+
|
|
230
|
+
expect(instance).toBeInstanceOf(Queue);
|
|
231
|
+
});
|
|
117
232
|
|
|
118
|
-
|
|
119
|
-
|
|
233
|
+
it("should not allow direct injection of the queue", () => {
|
|
234
|
+
expect(PlatformTest.get(Queue)).not.toBeInstanceOf(Queue);
|
|
235
|
+
});
|
|
120
236
|
});
|
|
121
237
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const job = {
|
|
126
|
-
name: "regular",
|
|
127
|
-
queueName: "default",
|
|
128
|
-
data: {test: "test"}
|
|
129
|
-
};
|
|
238
|
+
describe("workers", () => {
|
|
239
|
+
it("should get default", () => {
|
|
240
|
+
const instance = PlatformTest.get<Worker>("bullmq.worker.default");
|
|
130
241
|
|
|
131
|
-
|
|
242
|
+
expect(instance).toBeInstanceOf(Worker);
|
|
243
|
+
});
|
|
132
244
|
|
|
133
|
-
|
|
245
|
+
it.each(config.workerQueues)("should register worker(%s)", (queue) => {
|
|
246
|
+
const instance = PlatformTest.get<Worker>(`bullmq.worker.${queue}`);
|
|
134
247
|
|
|
135
|
-
|
|
248
|
+
expect(instance).toBeInstanceOf(Worker);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("should not register unspecified worker queue", () => {
|
|
252
|
+
expect(PlatformTest.get("bullmq.worker.bar")).toBeUndefined();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("should not allow direct injection of the worker", () => {
|
|
256
|
+
expect(PlatformTest.get(Worker)).not.toBeInstanceOf(Worker);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("should run worker and execute processor", async () => {
|
|
260
|
+
const bullMQModule = PlatformTest.get<BullMQModule>(BullMQModule);
|
|
261
|
+
const worker = PlatformTest.get<JobMethods>("bullmq.job.default.regular");
|
|
262
|
+
const job = {
|
|
263
|
+
name: "regular",
|
|
264
|
+
queueName: "default",
|
|
265
|
+
data: {test: "test"}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
jest.spyOn(worker, "handle").mockResolvedValueOnce(undefined as never);
|
|
269
|
+
|
|
270
|
+
await (bullMQModule as any).onProcess(job);
|
|
271
|
+
|
|
272
|
+
expect(worker.handle).toHaveBeenCalledWith({test: "test"}, job);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("should log warning when the worker doesn't exists", async () => {
|
|
276
|
+
const bullMQModule = PlatformTest.get<BullMQModule>(BullMQModule);
|
|
277
|
+
|
|
278
|
+
jest.spyOn(PlatformTest.injector.logger, "warn");
|
|
279
|
+
|
|
280
|
+
const job = {
|
|
281
|
+
name: "regular",
|
|
282
|
+
queueName: "toto",
|
|
283
|
+
data: {test: "test"}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
await (bullMQModule as any).onProcess(job);
|
|
287
|
+
|
|
288
|
+
expect(PlatformTest.injector.logger.warn).toHaveBeenCalledWith({
|
|
289
|
+
event: "BULLMQ_JOB_NOT_FOUND",
|
|
290
|
+
message: "Job regular toto not found"
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("should run worker, execute processor and handle error", async () => {
|
|
295
|
+
const bullMQModule = PlatformTest.get<BullMQModule>(BullMQModule);
|
|
296
|
+
const worker = PlatformTest.get<JobMethods>("bullmq.job.default.regular");
|
|
297
|
+
const job = {
|
|
298
|
+
name: "regular",
|
|
299
|
+
queueName: "default",
|
|
300
|
+
data: {test: "test"}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
jest.spyOn(PlatformTest.injector.logger, "error");
|
|
304
|
+
|
|
305
|
+
jest.spyOn(worker, "handle").mockRejectedValue(new Error("error") as never);
|
|
306
|
+
|
|
307
|
+
const error = await catchAsyncError(() => (bullMQModule as any).onProcess(job));
|
|
308
|
+
|
|
309
|
+
expect(worker.handle).toHaveBeenCalledWith({test: "test"}, job);
|
|
310
|
+
expect(PlatformTest.injector.logger.error).toHaveBeenCalledWith({
|
|
311
|
+
duration: expect.any(Number),
|
|
312
|
+
event: "BULLMQ_JOB_ERROR",
|
|
313
|
+
message: "error",
|
|
314
|
+
reqId: expect.any(String),
|
|
315
|
+
stack: expect.any(String),
|
|
316
|
+
time: expect.any(Object)
|
|
317
|
+
});
|
|
318
|
+
expect(error?.message).toEqual("error");
|
|
319
|
+
});
|
|
136
320
|
});
|
|
321
|
+
});
|
|
137
322
|
|
|
138
|
-
|
|
139
|
-
|
|
323
|
+
describe("with fallback controller", () => {
|
|
324
|
+
beforeEach(async () => {
|
|
325
|
+
@FallbackJobController("foo")
|
|
326
|
+
class FooFallbackController {
|
|
327
|
+
handle() {}
|
|
328
|
+
}
|
|
140
329
|
|
|
141
|
-
|
|
330
|
+
@FallbackJobController()
|
|
331
|
+
class FallbackController {
|
|
332
|
+
handle() {}
|
|
333
|
+
}
|
|
142
334
|
|
|
335
|
+
await PlatformTest.create({
|
|
336
|
+
bullmq: {
|
|
337
|
+
queues: ["default", "foo"],
|
|
338
|
+
connection: {}
|
|
339
|
+
},
|
|
340
|
+
imports: [
|
|
341
|
+
{
|
|
342
|
+
token: JobDispatcher,
|
|
343
|
+
use: instance(dispatcher)
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it("should run queue specific fallback job controller", async () => {
|
|
350
|
+
const bullMQModule = PlatformTest.get<BullMQModule>(BullMQModule);
|
|
351
|
+
const worker = PlatformTest.get<JobMethods>("bullmq.fallback-job.foo");
|
|
143
352
|
const job = {
|
|
144
|
-
name: "
|
|
145
|
-
queueName: "
|
|
353
|
+
name: "unknown-name",
|
|
354
|
+
queueName: "foo",
|
|
146
355
|
data: {test: "test"}
|
|
147
356
|
};
|
|
148
357
|
|
|
358
|
+
jest.spyOn(worker, "handle").mockResolvedValueOnce(undefined as never);
|
|
359
|
+
|
|
149
360
|
await (bullMQModule as any).onProcess(job);
|
|
150
361
|
|
|
151
|
-
expect(
|
|
152
|
-
event: "BULLMQ_JOB_NOT_FOUND",
|
|
153
|
-
message: "Job regular toto not found"
|
|
154
|
-
});
|
|
362
|
+
expect(worker.handle).toHaveBeenCalledWith({test: "test"}, job);
|
|
155
363
|
});
|
|
156
364
|
|
|
157
|
-
it("should run
|
|
365
|
+
it("should run overall fallback job controller", async () => {
|
|
158
366
|
const bullMQModule = PlatformTest.get<BullMQModule>(BullMQModule);
|
|
159
|
-
const worker = PlatformTest.get<JobMethods>("bullmq.job
|
|
367
|
+
const worker = PlatformTest.get<JobMethods>("bullmq.fallback-job");
|
|
160
368
|
const job = {
|
|
161
|
-
name: "
|
|
369
|
+
name: "unknown-name",
|
|
162
370
|
queueName: "default",
|
|
163
|
-
data: {test: "
|
|
371
|
+
data: {test: "123"}
|
|
164
372
|
};
|
|
165
373
|
|
|
166
|
-
jest.spyOn(
|
|
167
|
-
|
|
168
|
-
jest.spyOn(worker, "handle").mockRejectedValue(new Error("error") as never);
|
|
374
|
+
jest.spyOn(worker, "handle").mockResolvedValueOnce(undefined as never);
|
|
169
375
|
|
|
170
|
-
|
|
376
|
+
await (bullMQModule as any).onProcess(job);
|
|
171
377
|
|
|
172
|
-
expect(worker.handle).toHaveBeenCalledWith({test: "
|
|
173
|
-
expect(PlatformTest.injector.logger.error).toHaveBeenCalledWith({
|
|
174
|
-
duration: expect.any(Number),
|
|
175
|
-
event: "BULLMQ_JOB_ERROR",
|
|
176
|
-
message: "error",
|
|
177
|
-
reqId: expect.any(String),
|
|
178
|
-
stack: expect.any(String),
|
|
179
|
-
time: expect.any(Object)
|
|
180
|
-
});
|
|
181
|
-
expect(error?.message).toEqual("error");
|
|
378
|
+
expect(worker.handle).toHaveBeenCalledWith({test: "123"}, job);
|
|
182
379
|
});
|
|
183
380
|
});
|
|
184
381
|
});
|
|
185
|
-
|
|
186
|
-
it('skips initialization when no config is provided', async () => {
|
|
187
|
-
const injector = mock(InjectorService)
|
|
188
|
-
const dispatcher = mock(JobDispatcher);
|
|
189
|
-
await PlatformTest.create({
|
|
190
|
-
imports: [
|
|
191
|
-
{
|
|
192
|
-
token: InjectorService,
|
|
193
|
-
use: instance(injector),
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
token: JobDispatcher,
|
|
197
|
-
use: instance(dispatcher)
|
|
198
|
-
}
|
|
199
|
-
]
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
verify(injector.add(anyString(), anything())).never();
|
|
203
|
-
verify(dispatcher.dispatch(anything())).never()
|
|
204
|
-
});
|