@rvoh/psychic-workers 0.3.0 → 0.3.2
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/dist/cjs/src/background/BaseBackgroundedModel.js +105 -0
- package/dist/cjs/src/background/BaseBackgroundedService.js +71 -0
- package/dist/cjs/src/background/BaseScheduledService.js +51 -0
- package/dist/cjs/src/background/helpers/nameToRedisQueueName.js +10 -0
- package/dist/cjs/src/background/index.js +144 -68
- package/dist/cjs/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js +11 -0
- package/dist/cjs/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js +17 -0
- package/dist/cjs/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +11 -0
- package/dist/cjs/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +16 -0
- package/dist/cjs/src/psychic-app-workers/index.js +1 -1
- package/dist/cjs/src/types/utils.js +2 -0
- package/dist/esm/src/background/BaseBackgroundedModel.js +105 -0
- package/dist/esm/src/background/BaseBackgroundedService.js +71 -0
- package/dist/esm/src/background/BaseScheduledService.js +51 -0
- package/dist/esm/src/background/helpers/nameToRedisQueueName.js +7 -0
- package/dist/esm/src/background/index.js +134 -58
- package/dist/esm/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js +8 -0
- package/dist/esm/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js +14 -0
- package/dist/esm/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +8 -0
- package/dist/esm/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +13 -0
- package/dist/esm/src/index.js +1 -1
- package/dist/esm/src/psychic-app-workers/index.js +1 -1
- package/dist/esm/src/types/utils.js +1 -0
- package/dist/types/src/background/BaseBackgroundedModel.d.ts +108 -3
- package/dist/types/src/background/BaseBackgroundedService.d.ts +73 -2
- package/dist/types/src/background/BaseScheduledService.d.ts +53 -2
- package/dist/types/src/background/helpers/nameToRedisQueueName.d.ts +2 -0
- package/dist/types/src/background/index.d.ts +117 -32
- package/dist/types/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.d.ts +3 -0
- package/dist/types/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.d.ts +5 -0
- package/dist/types/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.d.ts +3 -0
- package/dist/types/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.d.ts +5 -0
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/psychic-app-workers/index.d.ts +4 -4
- package/dist/types/src/types/background.d.ts +47 -0
- package/package.json +2 -2
- /package/dist/cjs/src/{background/types.js → types/background.js} +0 -0
- /package/dist/esm/src/{background/types.js → types/background.js} +0 -0
- /package/dist/types/src/{background/types.d.ts → types/utils.d.ts} +0 -0
@@ -5,87 +5,100 @@ exports.stopBackgroundWorkers = stopBackgroundWorkers;
|
|
5
5
|
const dream_1 = require("@rvoh/dream");
|
6
6
|
const psychic_1 = require("@rvoh/psychic");
|
7
7
|
const bullmq_1 = require("bullmq");
|
8
|
-
const
|
8
|
+
const ActivatingBackgroundWorkersWithoutDefaultWorkerConnection_js_1 = require("../error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js");
|
9
|
+
const ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection_js_1 = require("../error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js");
|
10
|
+
const DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection_js_1 = require("../error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js");
|
11
|
+
const NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection_js_1 = require("../error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js");
|
9
12
|
const NoQueueForSpecifiedQueueName_js_1 = require("../error/background/NoQueueForSpecifiedQueueName.js");
|
10
13
|
const NoQueueForSpecifiedWorkstream_js_1 = require("../error/background/NoQueueForSpecifiedWorkstream.js");
|
11
14
|
const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
|
12
15
|
const index_js_1 = require("../psychic-app-workers/index.js");
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
`;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
class NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
22
|
-
queueName;
|
23
|
-
constructor(queueName) {
|
24
|
-
super();
|
25
|
-
this.queueName = queueName;
|
26
|
-
}
|
27
|
-
get message() {
|
28
|
-
return `
|
29
|
-
Native BullMQ options don't include a default queue connection, and the
|
30
|
-
${this.queueName} queue does not include a queue connection
|
31
|
-
`;
|
32
|
-
}
|
33
|
-
}
|
34
|
-
class ActivatingBackgroundWorkersWithoutDefaultWorkerConnection extends Error {
|
35
|
-
get message() {
|
36
|
-
return `
|
37
|
-
defaultWorkerConnection is required when activating workers. For example,
|
38
|
-
it may be omitted on webserver instances, but is required on worker instances.
|
39
|
-
`;
|
40
|
-
}
|
41
|
-
}
|
42
|
-
class ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection extends Error {
|
43
|
-
queueName;
|
44
|
-
constructor(queueName) {
|
45
|
-
super();
|
46
|
-
this.queueName = queueName;
|
47
|
-
}
|
48
|
-
get message() {
|
49
|
-
return `
|
50
|
-
defaultWorkerConnection is missing, and the ${this.queueName} queue does not
|
51
|
-
specify a workerConnection. A worker connection isrequired when activating workers.
|
52
|
-
For example, it may be omitted on webserver instances, but is required on worker instances.
|
53
|
-
`;
|
54
|
-
}
|
55
|
-
}
|
16
|
+
const nameToRedisQueueName_js_1 = require("./helpers/nameToRedisQueueName.js");
|
17
|
+
/**
|
18
|
+
* the underlying class driving the `background` singleton,
|
19
|
+
* available as an import from `psychic-workers`.
|
20
|
+
*/
|
56
21
|
class Background {
|
22
|
+
/**
|
23
|
+
* returns the default queue name for your app
|
24
|
+
*/
|
57
25
|
static get defaultQueueName() {
|
58
26
|
const psychicWorkersApp = index_js_1.default.getOrFail();
|
59
27
|
return `${(0, dream_1.pascalize)(psychicWorkersApp.psychicApp.appName)}BackgroundJobQueue`;
|
60
28
|
}
|
29
|
+
/**
|
30
|
+
* @internal
|
31
|
+
*
|
32
|
+
* returns the provided Worker class, or the Worker class from BullMQ
|
33
|
+
* if no override was provided. This is providable because BullMQ also
|
34
|
+
* offers a pro version, which requires you to provide custom classes.
|
35
|
+
*/
|
61
36
|
static get Worker() {
|
62
37
|
const psychicWorkersApp = index_js_1.default.getOrFail();
|
63
38
|
return (psychicWorkersApp.backgroundOptions.providers?.Worker || bullmq_1.Worker);
|
64
39
|
}
|
40
|
+
/**
|
41
|
+
* @internal
|
42
|
+
*
|
43
|
+
* returns the provided Queue class, or the Queue class from BullMQ
|
44
|
+
* if no override was provided. This is providable because BullMQ also
|
45
|
+
* offers a pro version, which requires you to provide custom classes.
|
46
|
+
*/
|
65
47
|
static get Queue() {
|
66
48
|
const psychicWorkersApp = index_js_1.default.getOrFail();
|
67
49
|
return (psychicWorkersApp.backgroundOptions.providers?.Queue || bullmq_1.Queue);
|
68
50
|
}
|
69
51
|
/**
|
52
|
+
* @internal
|
53
|
+
*
|
70
54
|
* Used when adding jobs to the default queue
|
71
55
|
*/
|
72
56
|
defaultQueue = null;
|
73
57
|
/**
|
58
|
+
* @internal
|
59
|
+
*
|
74
60
|
* Used when adding jobs to the default transitional queue
|
75
61
|
*/
|
76
62
|
defaultTransitionalQueue = null;
|
77
63
|
/**
|
64
|
+
* @internal
|
65
|
+
*
|
78
66
|
* Used when adding jobs to a named queue
|
79
67
|
*/
|
80
68
|
namedQueues = {};
|
69
|
+
/**
|
70
|
+
* @internal
|
71
|
+
*
|
72
|
+
* Used when adding grouped jobs
|
73
|
+
*/
|
81
74
|
groupNames = {};
|
75
|
+
/**
|
76
|
+
* @internal
|
77
|
+
*
|
78
|
+
* Used when adding workstreams
|
79
|
+
*/
|
82
80
|
workstreamNames = [];
|
83
81
|
/**
|
82
|
+
* @internal
|
83
|
+
*
|
84
84
|
* Used when adding jobs to a named transitioanl queue
|
85
85
|
*/
|
86
86
|
namedTransitionalQueues = {};
|
87
|
+
/**
|
88
|
+
* @internal
|
89
|
+
*
|
90
|
+
* All of the workers that are currently registered
|
91
|
+
*/
|
87
92
|
_workers = [];
|
93
|
+
/**
|
94
|
+
* @internal
|
95
|
+
*
|
96
|
+
* All of the redis connections that are currently registered
|
97
|
+
*/
|
88
98
|
redisConnections = [];
|
99
|
+
/**
|
100
|
+
* Establishes connection to BullMQ via redis
|
101
|
+
*/
|
89
102
|
connect({ activateWorkers = false, } = {}) {
|
90
103
|
if (this.defaultQueue)
|
91
104
|
return;
|
@@ -98,6 +111,9 @@ class Background {
|
|
98
111
|
this.simpleConnect(defaultBullMQQueueOptions, psychicWorkersApp.backgroundOptions, { activateWorkers });
|
99
112
|
}
|
100
113
|
}
|
114
|
+
/**
|
115
|
+
* Returns all the queues in your application
|
116
|
+
*/
|
101
117
|
get queues() {
|
102
118
|
return (0, dream_1.compact)([
|
103
119
|
this.defaultQueue,
|
@@ -106,6 +122,9 @@ class Background {
|
|
106
122
|
...Object.values(this.namedTransitionalQueues).map(queue => queue),
|
107
123
|
]);
|
108
124
|
}
|
125
|
+
/**
|
126
|
+
* Returns all the workers in your application
|
127
|
+
*/
|
109
128
|
get workers() {
|
110
129
|
return [...this._workers];
|
111
130
|
}
|
@@ -113,6 +132,9 @@ class Background {
|
|
113
132
|
await this.shutdown();
|
114
133
|
process.exit();
|
115
134
|
}
|
135
|
+
/**
|
136
|
+
* Shuts down workers, closes all redis connections
|
137
|
+
*/
|
116
138
|
async shutdown() {
|
117
139
|
await Promise.all(this._workers.map(worker => worker.close()));
|
118
140
|
const psychicWorkersApp = index_js_1.default.getOrFail();
|
@@ -122,6 +144,9 @@ class Background {
|
|
122
144
|
await (0, dream_1.closeAllDbConnections)();
|
123
145
|
await this.closeAllRedisConnections();
|
124
146
|
}
|
147
|
+
/**
|
148
|
+
* closes all redis connections for workers and queues
|
149
|
+
*/
|
125
150
|
async closeAllRedisConnections() {
|
126
151
|
for (const queue of this.queues) {
|
127
152
|
await queue.close();
|
@@ -138,6 +163,11 @@ class Background {
|
|
138
163
|
}
|
139
164
|
}
|
140
165
|
}
|
166
|
+
/**
|
167
|
+
* @internal
|
168
|
+
*
|
169
|
+
* connects to BullMQ using workstream-based arguments
|
170
|
+
*/
|
141
171
|
simpleConnect(defaultBullMQQueueOptions, backgroundOptions, { activateWorkers = false, activatingTransitionalWorkstreams = false, }) {
|
142
172
|
const defaultQueueConnection = backgroundOptions.defaultQueueConnection;
|
143
173
|
const defaultWorkerConnection = backgroundOptions.defaultWorkerConnection;
|
@@ -148,7 +178,7 @@ class Background {
|
|
148
178
|
// transitional queues must have the same names they had prior to making them
|
149
179
|
// transitional since the name is what identifies the queues and enables the
|
150
180
|
// queues to be worked off
|
151
|
-
const formattedQueueName =
|
181
|
+
const formattedQueueName = (0, nameToRedisQueueName_js_1.default)(Background.defaultQueueName, defaultQueueConnection);
|
152
182
|
///////////////////////////////
|
153
183
|
// create default workstream //
|
154
184
|
///////////////////////////////
|
@@ -170,7 +200,7 @@ class Background {
|
|
170
200
|
/////////////////////////////
|
171
201
|
if (activateWorkers) {
|
172
202
|
if (!defaultWorkerConnection)
|
173
|
-
throw new
|
203
|
+
throw new ActivatingBackgroundWorkersWithoutDefaultWorkerConnection_js_1.default();
|
174
204
|
const workerCount = backgroundOptions.defaultWorkstream?.workerCount ?? 1;
|
175
205
|
for (let i = 0; i < workerCount; i++) {
|
176
206
|
this._workers.push(new Background.Worker(formattedQueueName, async (job) => await this.doWork(job), {
|
@@ -196,7 +226,7 @@ class Background {
|
|
196
226
|
// transitional queues must have the same names they had prior to making them
|
197
227
|
// transitional since the name is what identifies the queues and enables the
|
198
228
|
// queues to be worked off
|
199
|
-
const namedWorkstreamFormattedQueueName =
|
229
|
+
const namedWorkstreamFormattedQueueName = (0, nameToRedisQueueName_js_1.default)(namedWorkstream.name, namedWorkstreamQueueConnection);
|
200
230
|
const namedQueue = new Background.Queue(namedWorkstreamFormattedQueueName, {
|
201
231
|
...defaultBullMQQueueOptions,
|
202
232
|
connection: namedWorkstreamQueueConnection,
|
@@ -213,7 +243,7 @@ class Background {
|
|
213
243
|
//////////////////////////
|
214
244
|
if (activateWorkers) {
|
215
245
|
if (!namedWorkstreamWorkerConnection)
|
216
|
-
throw new
|
246
|
+
throw new ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection_js_1.default(namedWorkstream.name);
|
217
247
|
const workerCount = namedWorkstream.workerCount ?? 1;
|
218
248
|
for (let i = 0; i < workerCount; i++) {
|
219
249
|
this._workers.push(new Background.Worker(namedWorkstreamFormattedQueueName, async (job) => await this.doWork(job), {
|
@@ -243,6 +273,11 @@ class Background {
|
|
243
273
|
});
|
244
274
|
}
|
245
275
|
}
|
276
|
+
/**
|
277
|
+
* @internal
|
278
|
+
*
|
279
|
+
* connects to BullMQ using native BullMQ arguments
|
280
|
+
*/
|
246
281
|
nativeBullMQConnect(defaultBullMQQueueOptions, backgroundOptions, { activateWorkers = false, }) {
|
247
282
|
const nativeBullMQ = backgroundOptions.nativeBullMQ;
|
248
283
|
const defaultQueueConnection = nativeBullMQ.defaultQueueOptions?.queueConnection || backgroundOptions.defaultQueueConnection;
|
@@ -252,8 +287,8 @@ class Background {
|
|
252
287
|
if (defaultWorkerConnection)
|
253
288
|
this.redisConnections.push(defaultWorkerConnection);
|
254
289
|
if (!defaultQueueConnection)
|
255
|
-
throw new
|
256
|
-
const formattedQueueName =
|
290
|
+
throw new DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection_js_1.default();
|
291
|
+
const formattedQueueName = (0, nameToRedisQueueName_js_1.default)(Background.defaultQueueName, defaultQueueConnection);
|
257
292
|
//////////////////////////
|
258
293
|
// create default queue //
|
259
294
|
//////////////////////////
|
@@ -270,7 +305,7 @@ class Background {
|
|
270
305
|
/////////////////////////////
|
271
306
|
if (activateWorkers) {
|
272
307
|
if (!defaultWorkerConnection)
|
273
|
-
throw new
|
308
|
+
throw new ActivatingBackgroundWorkersWithoutDefaultWorkerConnection_js_1.default();
|
274
309
|
const workerCount = nativeBullMQ.defaultWorkerCount ?? 1;
|
275
310
|
for (let i = 0; i < workerCount; i++) {
|
276
311
|
this._workers.push(new Background.Worker(formattedQueueName, async (job) => await this.doWork(job), {
|
@@ -287,6 +322,7 @@ class Background {
|
|
287
322
|
/////////////////////////
|
288
323
|
const namedQueueOptionsMap = nativeBullMQ.namedQueueOptions || {};
|
289
324
|
Object.keys(namedQueueOptionsMap).forEach(queueName => {
|
325
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
290
326
|
const namedQueueOptions = namedQueueOptionsMap[queueName];
|
291
327
|
if (namedQueueOptions.queueConnection)
|
292
328
|
this.redisConnections.push(namedQueueOptions.queueConnection);
|
@@ -295,8 +331,8 @@ class Background {
|
|
295
331
|
const namedQueueConnection = namedQueueOptions.queueConnection || defaultQueueConnection;
|
296
332
|
const namedWorkerConnection = namedQueueOptions.workerConnection || defaultWorkerConnection;
|
297
333
|
if (!namedQueueConnection)
|
298
|
-
throw new
|
299
|
-
const formattedQueuename =
|
334
|
+
throw new NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection_js_1.default(queueName);
|
335
|
+
const formattedQueuename = (0, nameToRedisQueueName_js_1.default)(queueName, namedQueueConnection);
|
300
336
|
this.namedQueues[queueName] = new Background.Queue(formattedQueuename, {
|
301
337
|
...defaultBullMQQueueOptions,
|
302
338
|
...namedQueueOptions,
|
@@ -309,11 +345,11 @@ class Background {
|
|
309
345
|
const extraWorkerOptions = extraWorkerOptionsMap[queueName];
|
310
346
|
const extraWorkerCount = extraWorkerOptions ? (extraWorkerOptions.workerCount ?? 1) : 0;
|
311
347
|
this.groupNames[queueName] ||= [];
|
312
|
-
if (extraWorkerOptions
|
348
|
+
if (extraWorkerOptions?.group?.id)
|
313
349
|
this.groupNames[queueName].push(extraWorkerOptions.group.id);
|
314
350
|
if (activateWorkers) {
|
315
351
|
if (!namedWorkerConnection)
|
316
|
-
throw new
|
352
|
+
throw new ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection_js_1.default(queueName);
|
317
353
|
for (let i = 0; i < extraWorkerCount; i++) {
|
318
354
|
this._workers.push(new Background.Worker(formattedQueuename, async (job) => await this.doWork(job), {
|
319
355
|
...extraWorkerOptions,
|
@@ -329,16 +365,34 @@ class Background {
|
|
329
365
|
// end: create named queues //
|
330
366
|
//////////////////////////////
|
331
367
|
}
|
368
|
+
/**
|
369
|
+
* starts background workers
|
370
|
+
*/
|
332
371
|
work() {
|
333
372
|
this.connect({ activateWorkers: true });
|
334
373
|
process.on('SIGTERM', () => {
|
335
|
-
void this.shutdownAndExit()
|
374
|
+
void this.shutdownAndExit()
|
375
|
+
.then(() => { })
|
376
|
+
.catch(() => { });
|
336
377
|
});
|
337
378
|
process.on('SIGINT', () => {
|
338
|
-
void this.shutdownAndExit()
|
379
|
+
void this.shutdownAndExit()
|
380
|
+
.then(() => { })
|
381
|
+
.catch(() => { });
|
339
382
|
});
|
340
383
|
}
|
341
|
-
|
384
|
+
/**
|
385
|
+
* adds the static method of a provided class to BullMQ
|
386
|
+
*
|
387
|
+
* @param ObjectClass - the class you wish to background
|
388
|
+
* @param method - the method you wish to background
|
389
|
+
* @param globalName - the globalName of the class you are processing
|
390
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
391
|
+
* @param delaySeconds - (optional) the number of seconds you wish to wait before allowing this job to process
|
392
|
+
* @param importKey - (optional) the import key for the class
|
393
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
394
|
+
*/
|
395
|
+
async staticMethod(ObjectClass, method, { globalName, delaySeconds, args = [], jobConfig = {}, }) {
|
342
396
|
this.connect();
|
343
397
|
await this._addToQueue(`BackgroundJobQueueStaticJob`, {
|
344
398
|
globalName,
|
@@ -346,11 +400,23 @@ class Background {
|
|
346
400
|
args,
|
347
401
|
}, {
|
348
402
|
delaySeconds,
|
349
|
-
jobConfig
|
403
|
+
jobConfig,
|
350
404
|
groupId: this.jobConfigToGroupId(jobConfig),
|
351
405
|
priority: this.jobConfigToPriority(jobConfig),
|
352
406
|
});
|
353
407
|
}
|
408
|
+
/**
|
409
|
+
* adds the static method of a provided class to BullMQ,
|
410
|
+
* to be scheduled to run at a specified cron pattern
|
411
|
+
*
|
412
|
+
* @param ObjectClass - the class you wish to background
|
413
|
+
* @param pattern - the cron string you wish to use to govern the scheduling for this job
|
414
|
+
* @param method - the method you wish to background
|
415
|
+
* @param globalName - the globalName of the class you are processing
|
416
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
417
|
+
* @param importKey - (optional) the import key for the class
|
418
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
419
|
+
*/
|
354
420
|
async scheduledMethod(ObjectClass, pattern, method, { globalName, args = [], jobConfig = {}, }) {
|
355
421
|
this.connect();
|
356
422
|
// `jobId` is used to determine uniqueness along with name and repeat pattern.
|
@@ -360,7 +426,10 @@ class Background {
|
|
360
426
|
//
|
361
427
|
// See: https://docs.bullmq.io/guide/jobs/repeatable
|
362
428
|
const jobId = `${ObjectClass.name}:${method}`;
|
363
|
-
|
429
|
+
const queueInstance = this.queueInstance(jobConfig);
|
430
|
+
if (!queueInstance)
|
431
|
+
throw new Error(`Missing queue for: ${jobConfig.queue?.toString()}`);
|
432
|
+
await queueInstance.add('BackgroundJobQueueStaticJob', {
|
364
433
|
globalName,
|
365
434
|
method,
|
366
435
|
args,
|
@@ -393,6 +462,16 @@ class Background {
|
|
393
462
|
}
|
394
463
|
return queueInstance;
|
395
464
|
}
|
465
|
+
/**
|
466
|
+
* adds the instance method of a provided dream model to BullMQ
|
467
|
+
*
|
468
|
+
* @param modelInstance - the dream model instance you wish to background
|
469
|
+
* @param method - the method you wish to background
|
470
|
+
* @param globalName - the globalName of the class you are processing
|
471
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
472
|
+
* @param importKey - (optional) the import key for the class
|
473
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
474
|
+
*/
|
396
475
|
async modelInstanceMethod(modelInstance, method, { delaySeconds, args = [], jobConfig = {}, }) {
|
397
476
|
this.connect();
|
398
477
|
await this._addToQueue('BackgroundJobQueueModelInstanceJob', {
|
@@ -402,7 +481,7 @@ class Background {
|
|
402
481
|
args,
|
403
482
|
}, {
|
404
483
|
delaySeconds,
|
405
|
-
jobConfig
|
484
|
+
jobConfig,
|
406
485
|
groupId: this.jobConfigToGroupId(jobConfig),
|
407
486
|
priority: this.jobConfigToPriority(jobConfig),
|
408
487
|
});
|
@@ -417,9 +496,12 @@ class Background {
|
|
417
496
|
const queue = new Background.Queue('TestQueue', { connection: {} });
|
418
497
|
const job = new bullmq_1.Job(queue, jobType, jobData, {});
|
419
498
|
await this.doWork(job);
|
499
|
+
return;
|
420
500
|
//
|
421
501
|
}
|
422
|
-
|
502
|
+
if (!queueInstance)
|
503
|
+
throw new Error(`missing queue: ${jobConfig?.queue?.toString() || 'N/A'}`);
|
504
|
+
if (groupId && priority) {
|
423
505
|
await queueInstance.add(jobType, jobData, {
|
424
506
|
delay,
|
425
507
|
group: {
|
@@ -521,9 +603,3 @@ exports.default = background;
|
|
521
603
|
async function stopBackgroundWorkers() {
|
522
604
|
await background.shutdown();
|
523
605
|
}
|
524
|
-
function nameToRedisQueueName(queueName, redis) {
|
525
|
-
queueName = queueName.replace(/\{|\}/g, '');
|
526
|
-
if (redis instanceof ioredis_1.Cluster)
|
527
|
-
return `{${queueName}}`;
|
528
|
-
return queueName;
|
529
|
-
}
|
package/dist/cjs/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class ActivatingBackgroundWorkersWithoutDefaultWorkerConnection extends Error {
|
4
|
+
get message() {
|
5
|
+
return `
|
6
|
+
defaultWorkerConnection is required when activating workers. For example,
|
7
|
+
it may be omitted on webserver instances, but is required on worker instances.
|
8
|
+
`;
|
9
|
+
}
|
10
|
+
}
|
11
|
+
exports.default = ActivatingBackgroundWorkersWithoutDefaultWorkerConnection;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection extends Error {
|
4
|
+
queueName;
|
5
|
+
constructor(queueName) {
|
6
|
+
super();
|
7
|
+
this.queueName = queueName;
|
8
|
+
}
|
9
|
+
get message() {
|
10
|
+
return `
|
11
|
+
defaultWorkerConnection is missing, and the ${this.queueName} queue does not
|
12
|
+
specify a workerConnection. A worker connection isrequired when activating workers.
|
13
|
+
For example, it may be omitted on webserver instances, but is required on worker instances.
|
14
|
+
`;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
exports.default = ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
4
|
+
get message() {
|
5
|
+
return `
|
6
|
+
Native BullMQ options don't include a default queue connection, and the
|
7
|
+
default config does not include a queue connection
|
8
|
+
`;
|
9
|
+
}
|
10
|
+
}
|
11
|
+
exports.default = DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
4
|
+
queueName;
|
5
|
+
constructor(queueName) {
|
6
|
+
super();
|
7
|
+
this.queueName = queueName;
|
8
|
+
}
|
9
|
+
get message() {
|
10
|
+
return `
|
11
|
+
Native BullMQ options don't include a default queue connection, and the
|
12
|
+
${this.queueName} queue does not include a queue connection
|
13
|
+
`;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
exports.default = NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const bullmq_1 = require("bullmq");
|
4
|
-
const index_js_1 = require("../background/index.js");
|
5
4
|
const cache_js_1 = require("./cache.js");
|
5
|
+
const index_js_1 = require("../background/index.js");
|
6
6
|
class PsychicAppWorkers {
|
7
7
|
static async init(psychicApp, cb) {
|
8
8
|
const psychicWorkersApp = new PsychicAppWorkers(psychicApp);
|
@@ -1,13 +1,50 @@
|
|
1
1
|
import { Dream } from '@rvoh/dream';
|
2
2
|
import background from './index.js';
|
3
3
|
export default class BaseBackgroundedModel extends Dream {
|
4
|
+
/**
|
5
|
+
* A getter meant to be overridden in child classes. This does
|
6
|
+
* not have to be explicitly provided, but if so, it would allow
|
7
|
+
* you to override the default behavior of anything backgrounded
|
8
|
+
* by this service, such as the priority or workstream.
|
9
|
+
*
|
10
|
+
* @returns {object} config - the background job config
|
11
|
+
* @returns {string} config.priority - 'default' | 'urgent' | 'not_urgent' | 'last'
|
12
|
+
* @returns {string} config.workstream - a workstream name. This would be the name of a workstream, as defined in conf/workers.ts
|
13
|
+
* @returns {string} config.queueId - the id of the BullMQ queue you wish to connect to. This can only be provided if workstream is not provided.
|
14
|
+
* @returns {string} config.groupId - the groupId of the BullMQ queue you wish to connect to. This can only be provided if workstream is not provided.
|
15
|
+
*/
|
4
16
|
static get backgroundJobConfig() {
|
5
17
|
return {};
|
6
18
|
}
|
19
|
+
/**
|
20
|
+
* @internal
|
21
|
+
*
|
22
|
+
* shadows the static `backgroundJobConfig` getter provided by the user.
|
23
|
+
* This should never be overridden, and is meant to provide easy access
|
24
|
+
* to the config from within an instance.
|
25
|
+
*/
|
7
26
|
get backgroundJobConfig() {
|
8
27
|
const klass = this.constructor;
|
9
28
|
return klass.backgroundJobConfig;
|
10
29
|
}
|
30
|
+
/**
|
31
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
32
|
+
* sending in the provided args.
|
33
|
+
*
|
34
|
+
* ```ts
|
35
|
+
* await User.background('myMethod', 'abc', 123)
|
36
|
+
* ```
|
37
|
+
* though calling background must be awaited, the resolution of the promise
|
38
|
+
* is an indication that the job was put in the queue, not that it has
|
39
|
+
* completed.
|
40
|
+
*
|
41
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
42
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
43
|
+
* before making assertions.
|
44
|
+
*
|
45
|
+
* @param methodName - the name of the static method you wish to run in the background
|
46
|
+
* @param args - a variadic list of arguments to be sent to your method
|
47
|
+
*/
|
11
48
|
static async background(methodName, ...args) {
|
12
49
|
const safeThis = this;
|
13
50
|
return await background.staticMethod(safeThis, methodName, {
|
@@ -16,6 +53,27 @@ export default class BaseBackgroundedModel extends Dream {
|
|
16
53
|
jobConfig: safeThis.backgroundJobConfig,
|
17
54
|
});
|
18
55
|
}
|
56
|
+
/**
|
57
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
58
|
+
* sending in the provided args, including a delay in seconds, which
|
59
|
+
* can be used to hold off the job for a certain amount of time after
|
60
|
+
* it is entered into the queue.
|
61
|
+
*
|
62
|
+
* ```ts
|
63
|
+
* await User.backgroundWithDelay('myMethod', 'abc', 123)
|
64
|
+
* ```
|
65
|
+
* though calling background must be awaited, the resolution of the promise
|
66
|
+
* is an indication that the job was put in the queue, not that it has
|
67
|
+
* completed.
|
68
|
+
*
|
69
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
70
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
71
|
+
* before making assertions.
|
72
|
+
*
|
73
|
+
* @param delaySeconds - the amount of time (in seconds) you want to hold off before allowing the job to run
|
74
|
+
* @param methodName - the name of the static method you wish to run in the background
|
75
|
+
* @param args - a variadic list of arguments to be sent to your method
|
76
|
+
*/
|
19
77
|
static async backgroundWithDelay(delaySeconds, methodName, ...args) {
|
20
78
|
const safeThis = this;
|
21
79
|
return await background.staticMethod(safeThis, methodName, {
|
@@ -25,10 +83,35 @@ export default class BaseBackgroundedModel extends Dream {
|
|
25
83
|
jobConfig: safeThis.backgroundJobConfig,
|
26
84
|
});
|
27
85
|
}
|
86
|
+
/**
|
87
|
+
* types composed by psychic must be provided, since psychic-workers leverages
|
88
|
+
* the sync command in psychic to read your backgroundable services and extract
|
89
|
+
* metadata, which can be used to help provide types for the underlying methods
|
90
|
+
* in psychic-workers.
|
91
|
+
*/
|
28
92
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
29
93
|
get psychicTypes() {
|
30
94
|
throw new Error('Must define psychicTypes getter in BackgroundedService class within your application');
|
31
95
|
}
|
96
|
+
/**
|
97
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
98
|
+
* sending in the provided args.
|
99
|
+
*
|
100
|
+
* ```ts
|
101
|
+
* const user = await User.lastOrFail()
|
102
|
+
* await user.background('myMethod', 'abc', 123)
|
103
|
+
* ```
|
104
|
+
* though calling background must be awaited, the resolution of the promise
|
105
|
+
* is an indication that the job was put in the queue, not that it has
|
106
|
+
* completed.
|
107
|
+
*
|
108
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
109
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
110
|
+
* before making assertions.
|
111
|
+
*
|
112
|
+
* @param methodName - the name of the static method you wish to run in the background
|
113
|
+
* @param args - a variadic list of arguments to be sent to your method
|
114
|
+
*/
|
32
115
|
async background(methodName, ...args) {
|
33
116
|
const safeThis = this;
|
34
117
|
return await background.modelInstanceMethod(safeThis, methodName, {
|
@@ -36,6 +119,28 @@ export default class BaseBackgroundedModel extends Dream {
|
|
36
119
|
jobConfig: safeThis.backgroundJobConfig,
|
37
120
|
});
|
38
121
|
}
|
122
|
+
/**
|
123
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
124
|
+
* sending in the provided args, including a delay in seconds, which
|
125
|
+
* can be used to hold off the job for a certain amount of time after
|
126
|
+
* it is entered into the queue.
|
127
|
+
*
|
128
|
+
* ```ts
|
129
|
+
* const user = await User.lastOrFail()
|
130
|
+
* await user.backgroundWithDelay('myMethod', 'abc', 123)
|
131
|
+
* ```
|
132
|
+
* though calling background must be awaited, the resolution of the promise
|
133
|
+
* is an indication that the job was put in the queue, not that it has
|
134
|
+
* completed.
|
135
|
+
*
|
136
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
137
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
138
|
+
* before making assertions.
|
139
|
+
*
|
140
|
+
* @param delaySeconds - the amount of time (in seconds) you want to hold off before allowing the job to run
|
141
|
+
* @param methodName - the name of the static method you wish to run in the background
|
142
|
+
* @param args - a variadic list of arguments to be sent to your method
|
143
|
+
*/
|
39
144
|
async backgroundWithDelay(delaySeconds, methodName, ...args) {
|
40
145
|
const safeThis = this;
|
41
146
|
return await background.modelInstanceMethod(safeThis, methodName, {
|