@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
@@ -1,18 +1,62 @@
|
|
1
1
|
import { GlobalNameNotSet } from '@rvoh/dream';
|
2
2
|
import background from './index.js';
|
3
3
|
export default class BaseBackgroundedService {
|
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
|
+
* Returns a unique global name for the given service.
|
23
|
+
*
|
24
|
+
* @returns A string representing a unique key for this service
|
25
|
+
*/
|
7
26
|
static get globalName() {
|
8
27
|
if (!this._globalName)
|
9
28
|
throw new GlobalNameNotSet(this);
|
10
29
|
return this._globalName;
|
11
30
|
}
|
31
|
+
/**
|
32
|
+
* @internal
|
33
|
+
*
|
34
|
+
* Used by PsychicApplicationWorkers during the load process
|
35
|
+
* for services to assign unique global names to each service
|
36
|
+
* based on the file name of that model.
|
37
|
+
*/
|
12
38
|
static setGlobalName(globalName) {
|
13
39
|
this._globalName = globalName;
|
14
40
|
}
|
15
41
|
static _globalName;
|
42
|
+
/**
|
43
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
44
|
+
* sending in the provided args.
|
45
|
+
*
|
46
|
+
* ```ts
|
47
|
+
* await MyBackgroundableClass.background('myMethod', 'abc', 123)
|
48
|
+
* ```
|
49
|
+
* though calling background must be awaited, the resolution of the promise
|
50
|
+
* is an indication that the job was put in the queue, not that it has
|
51
|
+
* completed.
|
52
|
+
*
|
53
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
54
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
55
|
+
* before making assertions.
|
56
|
+
*
|
57
|
+
* @param methodName - the name of the static method you wish to run in the background
|
58
|
+
* @param args - a variadic list of arguments to be sent to your method
|
59
|
+
*/
|
16
60
|
static async background(methodName, ...args) {
|
17
61
|
const safeThis = this;
|
18
62
|
return await background.staticMethod(safeThis, methodName, {
|
@@ -21,6 +65,27 @@ export default class BaseBackgroundedService {
|
|
21
65
|
jobConfig: safeThis.backgroundJobConfig,
|
22
66
|
});
|
23
67
|
}
|
68
|
+
/**
|
69
|
+
* runs the specified method in a background queue, driven by BullMQ,
|
70
|
+
* sending in the provided args, including a delay in seconds, which
|
71
|
+
* can be used to hold off the job for a certain amount of time after
|
72
|
+
* it is entered into the queue.
|
73
|
+
*
|
74
|
+
* ```ts
|
75
|
+
* await MyBackgroundableClass.backgroundWithDelay('myMethod', 'abc', 123)
|
76
|
+
* ```
|
77
|
+
* though calling background must be awaited, the resolution of the promise
|
78
|
+
* is an indication that the job was put in the queue, not that it has
|
79
|
+
* completed.
|
80
|
+
*
|
81
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
82
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
83
|
+
* before making assertions.
|
84
|
+
*
|
85
|
+
* @param delaySeconds - the amount of time (in seconds) you want to hold off before allowing the job to run
|
86
|
+
* @param methodName - the name of the static method you wish to run in the background
|
87
|
+
* @param args - a variadic list of arguments to be sent to your method
|
88
|
+
*/
|
24
89
|
static async backgroundWithDelay(delaySeconds, methodName, ...args) {
|
25
90
|
const safeThis = this;
|
26
91
|
return await background.staticMethod(safeThis, methodName, {
|
@@ -30,6 +95,12 @@ export default class BaseBackgroundedService {
|
|
30
95
|
jobConfig: safeThis.backgroundJobConfig,
|
31
96
|
});
|
32
97
|
}
|
98
|
+
/**
|
99
|
+
* types composed by psychic must be provided, since psychic-workers leverages
|
100
|
+
* the sync command in psychic to read your backgroundable services and extract
|
101
|
+
* metadata, which can be used to help provide types for the underlying methods
|
102
|
+
* in psychic-workers.
|
103
|
+
*/
|
33
104
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
34
105
|
get psychicTypes() {
|
35
106
|
throw new Error('Must define psychicTypes getter in BackgroundedService class within your application');
|
@@ -1,18 +1,63 @@
|
|
1
1
|
import { GlobalNameNotSet } from '@rvoh/dream';
|
2
2
|
import background from './index.js';
|
3
3
|
export default class BaseScheduledService {
|
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
|
+
* Returns a unique global name for the given service.
|
23
|
+
*
|
24
|
+
* @returns A string representing a unique key for this service
|
25
|
+
*/
|
7
26
|
static get globalName() {
|
8
27
|
if (!this._globalName)
|
9
28
|
throw new GlobalNameNotSet(this);
|
10
29
|
return this._globalName;
|
11
30
|
}
|
31
|
+
/**
|
32
|
+
* @internal
|
33
|
+
*
|
34
|
+
* Used by PsychicApplicationWorkers during the load process
|
35
|
+
* for services to assign unique global names to each service
|
36
|
+
* based on the file name of that model.
|
37
|
+
*/
|
12
38
|
static setGlobalName(globalName) {
|
13
39
|
this._globalName = globalName;
|
14
40
|
}
|
15
41
|
static _globalName;
|
42
|
+
/**
|
43
|
+
* Schedules a job to be run repeatedly at a certain cron interval
|
44
|
+
* sending in the provided args.
|
45
|
+
*
|
46
|
+
* ```ts
|
47
|
+
* await MySchedulableClass.schedule('0 * * * *', 'myHourlyMethod', 'abc', 123)
|
48
|
+
* ```
|
49
|
+
* though calling background must be awaited, the resolution of the promise
|
50
|
+
* is an indication that the job was put in the queue, not that it has
|
51
|
+
* completed.
|
52
|
+
*
|
53
|
+
* NOTE: in test environments, psychic will immediately invoke the underlying
|
54
|
+
* method, preventing you from needing to explicitly wait for queues to flush
|
55
|
+
* before making assertions.
|
56
|
+
*
|
57
|
+
* @param pattern - A cron string representing the time interval you wish this to run on
|
58
|
+
* @param methodName - the name of the static method you wish to run in the background
|
59
|
+
* @param args - a variadic list of arguments to be sent to your method
|
60
|
+
*/
|
16
61
|
static async schedule(pattern, methodName, ...args) {
|
17
62
|
const safeThis = this;
|
18
63
|
return await background.scheduledMethod(safeThis, pattern, methodName, {
|
@@ -21,6 +66,12 @@ export default class BaseScheduledService {
|
|
21
66
|
jobConfig: safeThis.backgroundJobConfig,
|
22
67
|
});
|
23
68
|
}
|
69
|
+
/**
|
70
|
+
* types composed by psychic must be provided, since psychic-workers leverages
|
71
|
+
* the sync command in psychic to read your backgroundable services and extract
|
72
|
+
* metadata, which can be used to help provide types for the underlying methods
|
73
|
+
* in psychic-workers.
|
74
|
+
*/
|
24
75
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
25
76
|
get psychicTypes() {
|
26
77
|
throw new Error('Must define psychicTypes getter in BackgroundedService class within your application');
|
@@ -1,87 +1,100 @@
|
|
1
1
|
import { closeAllDbConnections, compact, pascalize } from '@rvoh/dream';
|
2
2
|
import { PsychicApp } from '@rvoh/psychic';
|
3
3
|
import { Job, Queue, Worker } from 'bullmq';
|
4
|
-
import
|
4
|
+
import ActivatingBackgroundWorkersWithoutDefaultWorkerConnection from '../error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js';
|
5
|
+
import ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection from '../error/background/ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection.js';
|
6
|
+
import DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection from '../error/background/DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js';
|
7
|
+
import NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection from '../error/background/NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection.js';
|
5
8
|
import NoQueueForSpecifiedQueueName from '../error/background/NoQueueForSpecifiedQueueName.js';
|
6
9
|
import NoQueueForSpecifiedWorkstream from '../error/background/NoQueueForSpecifiedWorkstream.js';
|
7
10
|
import EnvInternal from '../helpers/EnvInternal.js';
|
8
11
|
import PsychicAppWorkers from '../psychic-app-workers/index.js';
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
`;
|
15
|
-
}
|
16
|
-
}
|
17
|
-
class NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
18
|
-
queueName;
|
19
|
-
constructor(queueName) {
|
20
|
-
super();
|
21
|
-
this.queueName = queueName;
|
22
|
-
}
|
23
|
-
get message() {
|
24
|
-
return `
|
25
|
-
Native BullMQ options don't include a default queue connection, and the
|
26
|
-
${this.queueName} queue does not include a queue connection
|
27
|
-
`;
|
28
|
-
}
|
29
|
-
}
|
30
|
-
class ActivatingBackgroundWorkersWithoutDefaultWorkerConnection extends Error {
|
31
|
-
get message() {
|
32
|
-
return `
|
33
|
-
defaultWorkerConnection is required when activating workers. For example,
|
34
|
-
it may be omitted on webserver instances, but is required on worker instances.
|
35
|
-
`;
|
36
|
-
}
|
37
|
-
}
|
38
|
-
class ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection extends Error {
|
39
|
-
queueName;
|
40
|
-
constructor(queueName) {
|
41
|
-
super();
|
42
|
-
this.queueName = queueName;
|
43
|
-
}
|
44
|
-
get message() {
|
45
|
-
return `
|
46
|
-
defaultWorkerConnection is missing, and the ${this.queueName} queue does not
|
47
|
-
specify a workerConnection. A worker connection isrequired when activating workers.
|
48
|
-
For example, it may be omitted on webserver instances, but is required on worker instances.
|
49
|
-
`;
|
50
|
-
}
|
51
|
-
}
|
12
|
+
import nameToRedisQueueName from './helpers/nameToRedisQueueName.js';
|
13
|
+
/**
|
14
|
+
* the underlying class driving the `background` singleton,
|
15
|
+
* available as an import from `psychic-workers`.
|
16
|
+
*/
|
52
17
|
export class Background {
|
18
|
+
/**
|
19
|
+
* returns the default queue name for your app
|
20
|
+
*/
|
53
21
|
static get defaultQueueName() {
|
54
22
|
const psychicWorkersApp = PsychicAppWorkers.getOrFail();
|
55
23
|
return `${pascalize(psychicWorkersApp.psychicApp.appName)}BackgroundJobQueue`;
|
56
24
|
}
|
25
|
+
/**
|
26
|
+
* @internal
|
27
|
+
*
|
28
|
+
* returns the provided Worker class, or the Worker class from BullMQ
|
29
|
+
* if no override was provided. This is providable because BullMQ also
|
30
|
+
* offers a pro version, which requires you to provide custom classes.
|
31
|
+
*/
|
57
32
|
static get Worker() {
|
58
33
|
const psychicWorkersApp = PsychicAppWorkers.getOrFail();
|
59
34
|
return (psychicWorkersApp.backgroundOptions.providers?.Worker || Worker);
|
60
35
|
}
|
36
|
+
/**
|
37
|
+
* @internal
|
38
|
+
*
|
39
|
+
* returns the provided Queue class, or the Queue class from BullMQ
|
40
|
+
* if no override was provided. This is providable because BullMQ also
|
41
|
+
* offers a pro version, which requires you to provide custom classes.
|
42
|
+
*/
|
61
43
|
static get Queue() {
|
62
44
|
const psychicWorkersApp = PsychicAppWorkers.getOrFail();
|
63
45
|
return (psychicWorkersApp.backgroundOptions.providers?.Queue || Queue);
|
64
46
|
}
|
65
47
|
/**
|
48
|
+
* @internal
|
49
|
+
*
|
66
50
|
* Used when adding jobs to the default queue
|
67
51
|
*/
|
68
52
|
defaultQueue = null;
|
69
53
|
/**
|
54
|
+
* @internal
|
55
|
+
*
|
70
56
|
* Used when adding jobs to the default transitional queue
|
71
57
|
*/
|
72
58
|
defaultTransitionalQueue = null;
|
73
59
|
/**
|
60
|
+
* @internal
|
61
|
+
*
|
74
62
|
* Used when adding jobs to a named queue
|
75
63
|
*/
|
76
64
|
namedQueues = {};
|
65
|
+
/**
|
66
|
+
* @internal
|
67
|
+
*
|
68
|
+
* Used when adding grouped jobs
|
69
|
+
*/
|
77
70
|
groupNames = {};
|
71
|
+
/**
|
72
|
+
* @internal
|
73
|
+
*
|
74
|
+
* Used when adding workstreams
|
75
|
+
*/
|
78
76
|
workstreamNames = [];
|
79
77
|
/**
|
78
|
+
* @internal
|
79
|
+
*
|
80
80
|
* Used when adding jobs to a named transitioanl queue
|
81
81
|
*/
|
82
82
|
namedTransitionalQueues = {};
|
83
|
+
/**
|
84
|
+
* @internal
|
85
|
+
*
|
86
|
+
* All of the workers that are currently registered
|
87
|
+
*/
|
83
88
|
_workers = [];
|
89
|
+
/**
|
90
|
+
* @internal
|
91
|
+
*
|
92
|
+
* All of the redis connections that are currently registered
|
93
|
+
*/
|
84
94
|
redisConnections = [];
|
95
|
+
/**
|
96
|
+
* Establishes connection to BullMQ via redis
|
97
|
+
*/
|
85
98
|
connect({ activateWorkers = false, } = {}) {
|
86
99
|
if (this.defaultQueue)
|
87
100
|
return;
|
@@ -94,6 +107,9 @@ export class Background {
|
|
94
107
|
this.simpleConnect(defaultBullMQQueueOptions, psychicWorkersApp.backgroundOptions, { activateWorkers });
|
95
108
|
}
|
96
109
|
}
|
110
|
+
/**
|
111
|
+
* Returns all the queues in your application
|
112
|
+
*/
|
97
113
|
get queues() {
|
98
114
|
return compact([
|
99
115
|
this.defaultQueue,
|
@@ -102,6 +118,9 @@ export class Background {
|
|
102
118
|
...Object.values(this.namedTransitionalQueues).map(queue => queue),
|
103
119
|
]);
|
104
120
|
}
|
121
|
+
/**
|
122
|
+
* Returns all the workers in your application
|
123
|
+
*/
|
105
124
|
get workers() {
|
106
125
|
return [...this._workers];
|
107
126
|
}
|
@@ -109,6 +128,9 @@ export class Background {
|
|
109
128
|
await this.shutdown();
|
110
129
|
process.exit();
|
111
130
|
}
|
131
|
+
/**
|
132
|
+
* Shuts down workers, closes all redis connections
|
133
|
+
*/
|
112
134
|
async shutdown() {
|
113
135
|
await Promise.all(this._workers.map(worker => worker.close()));
|
114
136
|
const psychicWorkersApp = PsychicAppWorkers.getOrFail();
|
@@ -118,6 +140,9 @@ export class Background {
|
|
118
140
|
await closeAllDbConnections();
|
119
141
|
await this.closeAllRedisConnections();
|
120
142
|
}
|
143
|
+
/**
|
144
|
+
* closes all redis connections for workers and queues
|
145
|
+
*/
|
121
146
|
async closeAllRedisConnections() {
|
122
147
|
for (const queue of this.queues) {
|
123
148
|
await queue.close();
|
@@ -134,6 +159,11 @@ export class Background {
|
|
134
159
|
}
|
135
160
|
}
|
136
161
|
}
|
162
|
+
/**
|
163
|
+
* @internal
|
164
|
+
*
|
165
|
+
* connects to BullMQ using workstream-based arguments
|
166
|
+
*/
|
137
167
|
simpleConnect(defaultBullMQQueueOptions, backgroundOptions, { activateWorkers = false, activatingTransitionalWorkstreams = false, }) {
|
138
168
|
const defaultQueueConnection = backgroundOptions.defaultQueueConnection;
|
139
169
|
const defaultWorkerConnection = backgroundOptions.defaultWorkerConnection;
|
@@ -239,6 +269,11 @@ export class Background {
|
|
239
269
|
});
|
240
270
|
}
|
241
271
|
}
|
272
|
+
/**
|
273
|
+
* @internal
|
274
|
+
*
|
275
|
+
* connects to BullMQ using native BullMQ arguments
|
276
|
+
*/
|
242
277
|
nativeBullMQConnect(defaultBullMQQueueOptions, backgroundOptions, { activateWorkers = false, }) {
|
243
278
|
const nativeBullMQ = backgroundOptions.nativeBullMQ;
|
244
279
|
const defaultQueueConnection = nativeBullMQ.defaultQueueOptions?.queueConnection || backgroundOptions.defaultQueueConnection;
|
@@ -283,6 +318,7 @@ export class Background {
|
|
283
318
|
/////////////////////////
|
284
319
|
const namedQueueOptionsMap = nativeBullMQ.namedQueueOptions || {};
|
285
320
|
Object.keys(namedQueueOptionsMap).forEach(queueName => {
|
321
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
286
322
|
const namedQueueOptions = namedQueueOptionsMap[queueName];
|
287
323
|
if (namedQueueOptions.queueConnection)
|
288
324
|
this.redisConnections.push(namedQueueOptions.queueConnection);
|
@@ -305,7 +341,7 @@ export class Background {
|
|
305
341
|
const extraWorkerOptions = extraWorkerOptionsMap[queueName];
|
306
342
|
const extraWorkerCount = extraWorkerOptions ? (extraWorkerOptions.workerCount ?? 1) : 0;
|
307
343
|
this.groupNames[queueName] ||= [];
|
308
|
-
if (extraWorkerOptions
|
344
|
+
if (extraWorkerOptions?.group?.id)
|
309
345
|
this.groupNames[queueName].push(extraWorkerOptions.group.id);
|
310
346
|
if (activateWorkers) {
|
311
347
|
if (!namedWorkerConnection)
|
@@ -325,16 +361,34 @@ export class Background {
|
|
325
361
|
// end: create named queues //
|
326
362
|
//////////////////////////////
|
327
363
|
}
|
364
|
+
/**
|
365
|
+
* starts background workers
|
366
|
+
*/
|
328
367
|
work() {
|
329
368
|
this.connect({ activateWorkers: true });
|
330
369
|
process.on('SIGTERM', () => {
|
331
|
-
void this.shutdownAndExit()
|
370
|
+
void this.shutdownAndExit()
|
371
|
+
.then(() => { })
|
372
|
+
.catch(() => { });
|
332
373
|
});
|
333
374
|
process.on('SIGINT', () => {
|
334
|
-
void this.shutdownAndExit()
|
375
|
+
void this.shutdownAndExit()
|
376
|
+
.then(() => { })
|
377
|
+
.catch(() => { });
|
335
378
|
});
|
336
379
|
}
|
337
|
-
|
380
|
+
/**
|
381
|
+
* adds the static method of a provided class to BullMQ
|
382
|
+
*
|
383
|
+
* @param ObjectClass - the class you wish to background
|
384
|
+
* @param method - the method you wish to background
|
385
|
+
* @param globalName - the globalName of the class you are processing
|
386
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
387
|
+
* @param delaySeconds - (optional) the number of seconds you wish to wait before allowing this job to process
|
388
|
+
* @param importKey - (optional) the import key for the class
|
389
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
390
|
+
*/
|
391
|
+
async staticMethod(ObjectClass, method, { globalName, delaySeconds, args = [], jobConfig = {}, }) {
|
338
392
|
this.connect();
|
339
393
|
await this._addToQueue(`BackgroundJobQueueStaticJob`, {
|
340
394
|
globalName,
|
@@ -342,11 +396,23 @@ export class Background {
|
|
342
396
|
args,
|
343
397
|
}, {
|
344
398
|
delaySeconds,
|
345
|
-
jobConfig
|
399
|
+
jobConfig,
|
346
400
|
groupId: this.jobConfigToGroupId(jobConfig),
|
347
401
|
priority: this.jobConfigToPriority(jobConfig),
|
348
402
|
});
|
349
403
|
}
|
404
|
+
/**
|
405
|
+
* adds the static method of a provided class to BullMQ,
|
406
|
+
* to be scheduled to run at a specified cron pattern
|
407
|
+
*
|
408
|
+
* @param ObjectClass - the class you wish to background
|
409
|
+
* @param pattern - the cron string you wish to use to govern the scheduling for this job
|
410
|
+
* @param method - the method you wish to background
|
411
|
+
* @param globalName - the globalName of the class you are processing
|
412
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
413
|
+
* @param importKey - (optional) the import key for the class
|
414
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
415
|
+
*/
|
350
416
|
async scheduledMethod(ObjectClass, pattern, method, { globalName, args = [], jobConfig = {}, }) {
|
351
417
|
this.connect();
|
352
418
|
// `jobId` is used to determine uniqueness along with name and repeat pattern.
|
@@ -356,7 +422,10 @@ export class Background {
|
|
356
422
|
//
|
357
423
|
// See: https://docs.bullmq.io/guide/jobs/repeatable
|
358
424
|
const jobId = `${ObjectClass.name}:${method}`;
|
359
|
-
|
425
|
+
const queueInstance = this.queueInstance(jobConfig);
|
426
|
+
if (!queueInstance)
|
427
|
+
throw new Error(`Missing queue for: ${jobConfig.queue?.toString()}`);
|
428
|
+
await queueInstance.add('BackgroundJobQueueStaticJob', {
|
360
429
|
globalName,
|
361
430
|
method,
|
362
431
|
args,
|
@@ -389,6 +458,16 @@ export class Background {
|
|
389
458
|
}
|
390
459
|
return queueInstance;
|
391
460
|
}
|
461
|
+
/**
|
462
|
+
* adds the instance method of a provided dream model to BullMQ
|
463
|
+
*
|
464
|
+
* @param modelInstance - the dream model instance you wish to background
|
465
|
+
* @param method - the method you wish to background
|
466
|
+
* @param globalName - the globalName of the class you are processing
|
467
|
+
* @param args - (optional) a list of arguments to provide to your method when it is called
|
468
|
+
* @param importKey - (optional) the import key for the class
|
469
|
+
* @param jobConfig - (optional) the background job config to use when backgrounding this method
|
470
|
+
*/
|
392
471
|
async modelInstanceMethod(modelInstance, method, { delaySeconds, args = [], jobConfig = {}, }) {
|
393
472
|
this.connect();
|
394
473
|
await this._addToQueue('BackgroundJobQueueModelInstanceJob', {
|
@@ -398,7 +477,7 @@ export class Background {
|
|
398
477
|
args,
|
399
478
|
}, {
|
400
479
|
delaySeconds,
|
401
|
-
jobConfig
|
480
|
+
jobConfig,
|
402
481
|
groupId: this.jobConfigToGroupId(jobConfig),
|
403
482
|
priority: this.jobConfigToPriority(jobConfig),
|
404
483
|
});
|
@@ -413,9 +492,12 @@ export class Background {
|
|
413
492
|
const queue = new Background.Queue('TestQueue', { connection: {} });
|
414
493
|
const job = new Job(queue, jobType, jobData, {});
|
415
494
|
await this.doWork(job);
|
495
|
+
return;
|
416
496
|
//
|
417
497
|
}
|
418
|
-
|
498
|
+
if (!queueInstance)
|
499
|
+
throw new Error(`missing queue: ${jobConfig?.queue?.toString() || 'N/A'}`);
|
500
|
+
if (groupId && priority) {
|
419
501
|
await queueInstance.add(jobType, jobData, {
|
420
502
|
delay,
|
421
503
|
group: {
|
@@ -516,9 +598,3 @@ export default background;
|
|
516
598
|
export async function stopBackgroundWorkers() {
|
517
599
|
await background.shutdown();
|
518
600
|
}
|
519
|
-
function nameToRedisQueueName(queueName, redis) {
|
520
|
-
queueName = queueName.replace(/\{|\}/g, '');
|
521
|
-
if (redis instanceof Cluster)
|
522
|
-
return `{${queueName}}`;
|
523
|
-
return queueName;
|
524
|
-
}
|
package/dist/esm/src/error/background/ActivatingBackgroundWorkersWithoutDefaultWorkerConnection.js
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export default class ActivatingBackgroundWorkersWithoutDefaultWorkerConnection extends Error {
|
2
|
+
get message() {
|
3
|
+
return `
|
4
|
+
defaultWorkerConnection is required when activating workers. For example,
|
5
|
+
it may be omitted on webserver instances, but is required on worker instances.
|
6
|
+
`;
|
7
|
+
}
|
8
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export default class ActivatingNamedQueueBackgroundWorkersWithoutWorkerConnection extends Error {
|
2
|
+
queueName;
|
3
|
+
constructor(queueName) {
|
4
|
+
super();
|
5
|
+
this.queueName = queueName;
|
6
|
+
}
|
7
|
+
get message() {
|
8
|
+
return `
|
9
|
+
defaultWorkerConnection is missing, and the ${this.queueName} queue does not
|
10
|
+
specify a workerConnection. A worker connection isrequired when activating workers.
|
11
|
+
For example, it may be omitted on webserver instances, but is required on worker instances.
|
12
|
+
`;
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export default class DefaultBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
2
|
+
get message() {
|
3
|
+
return `
|
4
|
+
Native BullMQ options don't include a default queue connection, and the
|
5
|
+
default config does not include a queue connection
|
6
|
+
`;
|
7
|
+
}
|
8
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
export default class NamedBullMQNativeOptionsMissingQueueConnectionAndDefaultQueueConnection extends Error {
|
2
|
+
queueName;
|
3
|
+
constructor(queueName) {
|
4
|
+
super();
|
5
|
+
this.queueName = queueName;
|
6
|
+
}
|
7
|
+
get message() {
|
8
|
+
return `
|
9
|
+
Native BullMQ options don't include a default queue connection, and the
|
10
|
+
${this.queueName} queue does not include a queue connection
|
11
|
+
`;
|
12
|
+
}
|
13
|
+
}
|
package/dist/esm/src/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export { default as background, Background, stopBackgroundWorkers
|
1
|
+
export { default as background, Background, stopBackgroundWorkers } from './background/index.js';
|
2
2
|
export { default as BaseBackgroundedModel } from './background/BaseBackgroundedModel.js';
|
3
3
|
export { default as BaseBackgroundedService } from './background/BaseBackgroundedService.js';
|
4
4
|
export { default as BaseScheduledService } from './background/BaseScheduledService.js';
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Queue, Worker } from 'bullmq';
|
2
|
-
import background from '../background/index.js';
|
3
2
|
import { cachePsychicWorkersApp, getCachedPsychicWorkersAppOrFail } from './cache.js';
|
3
|
+
import background from '../background/index.js';
|
4
4
|
export default class PsychicAppWorkers {
|
5
5
|
static async init(psychicApp, cb) {
|
6
6
|
const psychicWorkersApp = new PsychicAppWorkers(psychicApp);
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|