@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.
Files changed (39) hide show
  1. package/dist/cjs/src/background/BaseBackgroundedModel.js +105 -0
  2. package/dist/cjs/src/background/BaseBackgroundedService.js +71 -0
  3. package/dist/cjs/src/background/BaseScheduledService.js +51 -0
  4. package/dist/cjs/src/background/helpers/nameToRedisQueueName.js +10 -0
  5. package/dist/cjs/src/background/index.js +144 -68
  6. package/dist/cjs/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js +11 -0
  7. package/dist/cjs/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js +17 -0
  8. package/dist/cjs/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +11 -0
  9. package/dist/cjs/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +16 -0
  10. package/dist/cjs/src/psychic-app-workers/index.js +1 -1
  11. package/dist/cjs/src/types/utils.js +2 -0
  12. package/dist/esm/src/background/BaseBackgroundedModel.js +105 -0
  13. package/dist/esm/src/background/BaseBackgroundedService.js +71 -0
  14. package/dist/esm/src/background/BaseScheduledService.js +51 -0
  15. package/dist/esm/src/background/helpers/nameToRedisQueueName.js +7 -0
  16. package/dist/esm/src/background/index.js +134 -58
  17. package/dist/esm/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js +8 -0
  18. package/dist/esm/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js +14 -0
  19. package/dist/esm/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +8 -0
  20. package/dist/esm/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js +13 -0
  21. package/dist/esm/src/index.js +1 -1
  22. package/dist/esm/src/psychic-app-workers/index.js +1 -1
  23. package/dist/esm/src/types/utils.js +1 -0
  24. package/dist/types/src/background/BaseBackgroundedModel.d.ts +108 -3
  25. package/dist/types/src/background/BaseBackgroundedService.d.ts +73 -2
  26. package/dist/types/src/background/BaseScheduledService.d.ts +53 -2
  27. package/dist/types/src/background/helpers/nameToRedisQueueName.d.ts +2 -0
  28. package/dist/types/src/background/index.d.ts +117 -32
  29. package/dist/types/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.d.ts +3 -0
  30. package/dist/types/src/error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.d.ts +5 -0
  31. package/dist/types/src/error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.d.ts +3 -0
  32. package/dist/types/src/error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.d.ts +5 -0
  33. package/dist/types/src/index.d.ts +2 -1
  34. package/dist/types/src/psychic-app-workers/index.d.ts +4 -4
  35. package/dist/types/src/types/background.d.ts +47 -0
  36. package/package.json +2 -2
  37. /package/dist/cjs/src/{background/types.js → types/background.js} +0 -0
  38. /package/dist/esm/src/{background/types.js → types/background.js} +0 -0
  39. /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 ioredis_1 = require("ioredis");
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
- class DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
14
- get message() {
15
- return `
16
- Native BullMQ options don't include a default queue connection, and the
17
- default config does not include a queue connection
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 = nameToRedisQueueName(Background.defaultQueueName, defaultQueueConnection);
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 ActivatingBackgroundWorkersWithoutDefaultWorkerConnection();
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 = nameToRedisQueueName(namedWorkstream.name, namedWorkstreamQueueConnection);
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 ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection(namedWorkstream.name);
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 DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection();
256
- const formattedQueueName = nameToRedisQueueName(Background.defaultQueueName, defaultQueueConnection);
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 ActivatingBackgroundWorkersWithoutDefaultWorkerConnection();
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 NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection(queueName);
299
- const formattedQueuename = nameToRedisQueueName(queueName, namedQueueConnection);
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.group?.id)
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 ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection(queueName);
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
- async staticMethod(ObjectClass, method, { delaySeconds, globalName, args = [], jobConfig = {}, }) {
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: 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
- await this.queueInstance(jobConfig).add('BackgroundJobQueueStaticJob', {
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: 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
- else if (groupId && priority) {
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
- }
@@ -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);
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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, {