@rvoh/psychic-workers 2.4.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/background/BaseBackgroundedModel.js +112 -19
- package/dist/cjs/src/background/BaseBackgroundedService.js +73 -9
- package/dist/cjs/src/background/BaseScheduledService.js +59 -1
- package/dist/cjs/src/background/index.js +418 -105
- package/dist/cjs/src/error/background/DebouncedJobOutpacesRateLimit.js +64 -0
- package/dist/cjs/src/error/background/DebouncedJobRequiresMinimumDelay.js +52 -0
- package/dist/cjs/src/error/background/NamedWorkstreamRateLimitMissingMaxOrDuration.js +31 -0
- package/dist/cjs/src/error/background/RateLimitedPsychicJob.js +82 -0
- package/dist/cjs/src/error/background/RateLimitedPsychicJobThrownFromWorkerWithoutLimiter.js +51 -0
- package/dist/cjs/src/package-exports/errors.js +7 -0
- package/dist/cjs/src/test-utils/WorkerTestUtils.js +79 -14
- package/dist/esm/src/background/BaseBackgroundedModel.js +112 -19
- package/dist/esm/src/background/BaseBackgroundedService.js +73 -9
- package/dist/esm/src/background/BaseScheduledService.js +59 -1
- package/dist/esm/src/background/index.js +418 -105
- package/dist/esm/src/error/background/DebouncedJobOutpacesRateLimit.js +64 -0
- package/dist/esm/src/error/background/DebouncedJobRequiresMinimumDelay.js +52 -0
- package/dist/esm/src/error/background/NamedWorkstreamRateLimitMissingMaxOrDuration.js +31 -0
- package/dist/esm/src/error/background/RateLimitedPsychicJob.js +82 -0
- package/dist/esm/src/error/background/RateLimitedPsychicJobThrownFromWorkerWithoutLimiter.js +51 -0
- package/dist/esm/src/package-exports/errors.js +7 -0
- package/dist/esm/src/test-utils/WorkerTestUtils.js +79 -14
- package/dist/types/src/background/BaseBackgroundedModel.d.ts +97 -20
- package/dist/types/src/background/BaseBackgroundedService.d.ts +61 -10
- package/dist/types/src/background/BaseScheduledService.d.ts +54 -1
- package/dist/types/src/background/index.d.ts +137 -5
- package/dist/types/src/error/background/DebouncedJobOutpacesRateLimit.d.ts +31 -0
- package/dist/types/src/error/background/DebouncedJobRequiresMinimumDelay.d.ts +23 -0
- package/dist/types/src/error/background/NamedWorkstreamRateLimitMissingMaxOrDuration.d.ts +16 -0
- package/dist/types/src/error/background/RateLimitedPsychicJob.d.ts +73 -0
- package/dist/types/src/error/background/RateLimitedPsychicJobThrownFromWorkerWithoutLimiter.d.ts +16 -0
- package/dist/types/src/package-exports/errors.d.ts +1 -0
- package/dist/types/src/psychic-app-workers/index.d.ts +102 -53
- package/dist/types/src/test-utils/WorkerTestUtils.d.ts +32 -1
- package/dist/types/src/types/background.d.ts +100 -4
- package/package.json +9 -8
|
@@ -64,7 +64,25 @@ export interface BullMQNativeWorkerOptions extends WorkerOptions {
|
|
|
64
64
|
concurrency?: number;
|
|
65
65
|
priority?: number;
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* How many jobs each worker built from this configuration runs at once
|
|
69
|
+
* (https://docs.bullmq.io/guide/workers/concurrency).
|
|
70
|
+
*
|
|
71
|
+
* Native BullMQ mode writes none, so BullMQ's default of **1** applies unless
|
|
72
|
+
* this or `defaultBullMQWorkerOptions.concurrency` sets it. See
|
|
73
|
+
* `PsychicBackgroundWorkstreamOptions.concurrency`.
|
|
74
|
+
*/
|
|
67
75
|
concurrency?: number;
|
|
76
|
+
/**
|
|
77
|
+
* the number of workers to create with this configuration, in this process.
|
|
78
|
+
*
|
|
79
|
+
* Read **only** for `nativeBullMQ.namedQueueWorkers`, where it defaults to 1
|
|
80
|
+
* (a named queue with no entry in `namedQueueWorkers` gets no workers at
|
|
81
|
+
* all). It is *not* read for `nativeBullMQ.defaultWorkerOptions`: the default
|
|
82
|
+
* queue's worker count comes from `nativeBullMQ.defaultWorkerCount`. See
|
|
83
|
+
* `PsychicBackgroundWorkstreamOptions.workerCount` for the
|
|
84
|
+
* `workerCount × concurrency` product.
|
|
85
|
+
*/
|
|
68
86
|
workerCount?: number;
|
|
69
87
|
}
|
|
70
88
|
export interface PsychicBackgroundNativeBullMQOptions extends PsychicBackgroundSharedOptions {
|
|
@@ -82,26 +100,24 @@ export interface PsychicBackgroundNativeBullMQOptions extends PsychicBackgroundS
|
|
|
82
100
|
*/
|
|
83
101
|
namedQueueOptions?: Record<string, QueueOptionsWithConnectionInstance>;
|
|
84
102
|
/**
|
|
85
|
-
* Native BullMQ options
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* only used to supply the number of default workers that you want.
|
|
103
|
+
* Native BullMQ options for the default workers, spread over
|
|
104
|
+
* `defaultBullMQWorkerOptions` — where `concurrency`, `limiter` and every
|
|
105
|
+
* other BullMQ worker option for them comes from. A `workerCount` set here
|
|
106
|
+
* is never read; the count comes from `defaultWorkerCount` below.
|
|
90
107
|
*/
|
|
91
108
|
defaultWorkerOptions?: BullMQNativeWorkerOptions;
|
|
92
109
|
/**
|
|
93
|
-
* The number of default workers to run
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* many workers running off a single queue. This number determines
|
|
98
|
-
* the number of those default workers to provide.
|
|
110
|
+
* The number of default workers to run in this process, and the only source
|
|
111
|
+
* of that count in native mode. Defaults to 1, and takes effect only in a
|
|
112
|
+
* process that activates workers. See
|
|
113
|
+
* `PsychicBackgroundWorkstreamOptions.workerCount`.
|
|
99
114
|
*/
|
|
100
115
|
defaultWorkerCount?: number;
|
|
101
116
|
/**
|
|
102
|
-
* namedQueueWorkers are necessary to work off namedQueues
|
|
103
|
-
*
|
|
104
|
-
*
|
|
117
|
+
* namedQueueWorkers are necessary to work off namedQueues.
|
|
118
|
+
* A named queue's workers can be rate limited with BullMQ's `limiter`
|
|
119
|
+
* option (https://docs.bullmq.io/guide/rate-limiting; useful for
|
|
120
|
+
* interacting with external APIs) on open-source BullMQ and BullMQ Pro alike
|
|
105
121
|
*/
|
|
106
122
|
namedQueueWorkers?: Record<string, BullMQNativeWorkerOptions>;
|
|
107
123
|
};
|
|
@@ -138,24 +154,34 @@ export interface PsychicBackgroundSimpleOptions extends PsychicBackgroundSharedO
|
|
|
138
154
|
*/
|
|
139
155
|
defaultWorkerConnection: RedisOrRedisClusterConnection | undefined;
|
|
140
156
|
/**
|
|
141
|
-
*
|
|
142
|
-
* workstream.
|
|
143
|
-
*
|
|
157
|
+
* The default workstream, whose queue carries every job not backgrounded to a
|
|
158
|
+
* named workstream. Both fields mean exactly what they mean on a named
|
|
159
|
+
* workstream — see `PsychicBackgroundWorkstreamOptions.workerCount` and
|
|
160
|
+
* `.concurrency`.
|
|
144
161
|
*/
|
|
145
162
|
defaultWorkstream?: {
|
|
163
|
+
/** The number of workers working through the default queue, in this process. Defaults to 1. */
|
|
146
164
|
workerCount?: number;
|
|
165
|
+
/**
|
|
166
|
+
* How many jobs each default worker runs at once
|
|
167
|
+
* (https://docs.bullmq.io/guide/workers/concurrency). Left unset, psychic
|
|
168
|
+
* falls back to 10, as everywhere in simple mode. See
|
|
169
|
+
* `PsychicBackgroundWorkstreamOptions.concurrency`.
|
|
170
|
+
*/
|
|
147
171
|
concurrency?: number;
|
|
148
172
|
};
|
|
149
173
|
/**
|
|
150
174
|
* When running background jobs on BullMQ, each named workstream corresponds
|
|
151
|
-
* to a specific queue and
|
|
152
|
-
* a
|
|
153
|
-
*
|
|
154
|
-
* named workstreams are useful for dispersing queues among nodes in a Redis cluster
|
|
155
|
-
* and for running queues on different Redis instances
|
|
175
|
+
* to a specific queue, and jobs backgrounded to a named workstream are added
|
|
176
|
+
* with a group id equal to the workstream name (a BullMQ Pro concept, ignored
|
|
177
|
+
* by open-source BullMQ)
|
|
156
178
|
*
|
|
157
|
-
*
|
|
158
|
-
* for
|
|
179
|
+
* named workstreams are useful for dispersing queues among nodes in a Redis cluster,
|
|
180
|
+
* for running queues on different Redis instances, and for rate limiting, on
|
|
181
|
+
* open-source BullMQ and BullMQ Pro alike (see
|
|
182
|
+
* `PsychicBackgroundWorkstreamOptions.rateLimit`). A rate limit targets one external
|
|
183
|
+
* limit, so give each rate-limited service its own named workstream — and where a
|
|
184
|
+
* service meters its endpoints separately, one workstream per limit
|
|
159
185
|
*/
|
|
160
186
|
namedWorkstreams?: PsychicBackgroundWorkstreamOptions[];
|
|
161
187
|
/**
|
|
@@ -171,43 +197,66 @@ export interface PsychicBackgroundWorkstreamOptions {
|
|
|
171
197
|
*/
|
|
172
198
|
name: string;
|
|
173
199
|
/**
|
|
174
|
-
* The number of workers you want to run on this configuration
|
|
200
|
+
* The number of workers you want to run on this configuration, in **this
|
|
201
|
+
* process**. Defaults to 1. These are BullMQ `Worker` objects sharing the
|
|
202
|
+
* activating process's event loop, not forked processes, so raising this buys
|
|
203
|
+
* concurrent waiting rather than concurrent CPU.
|
|
204
|
+
*
|
|
205
|
+
* `workerCount × concurrency` is the ceiling on this workstream's jobs in
|
|
206
|
+
* flight in one process, and that product is what to size against a
|
|
207
|
+
* downstream limit such as a connection pool or an external API's quota.
|
|
175
208
|
*/
|
|
176
209
|
workerCount?: number;
|
|
177
|
-
concurrency?: number;
|
|
178
|
-
/**
|
|
179
|
-
* See https://docs.bullmq.io/bullmq-pro/groups/rate-limiting for documentation
|
|
180
|
-
* on rate limiting in BullMQ Pro (requires paid BullMQ Pro license)
|
|
181
|
-
*/
|
|
182
|
-
rateLimit?: {
|
|
183
|
-
max?: number;
|
|
184
|
-
duration?: number;
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
187
|
-
* Optional redis connection. If not provided, the default background redis connection will be used.
|
|
188
|
-
* See https://docs.bullmq.io/guide/going-to-production for the different settings to use between
|
|
189
|
-
* queue and worker connections.
|
|
190
|
-
*/
|
|
191
|
-
queueConnection?: RedisOrRedisClusterConnection;
|
|
192
|
-
workerConnection?: RedisOrRedisClusterConnection;
|
|
193
|
-
}
|
|
194
|
-
export interface PsychicBackgroundWorkstreamOptions {
|
|
195
|
-
/**
|
|
196
|
-
* This will be the name of the queue (and the group if using BullMQ Pro)
|
|
197
|
-
*/
|
|
198
|
-
name: string;
|
|
199
210
|
/**
|
|
200
|
-
*
|
|
211
|
+
* How many jobs each of this workstream's workers runs at once
|
|
212
|
+
* (https://docs.bullmq.io/guide/workers/concurrency).
|
|
213
|
+
*
|
|
214
|
+
* **In simple mode this defaults to 10.** Psychic always writes a
|
|
215
|
+
* `concurrency` onto a simple-mode worker, falling back to 10 when the
|
|
216
|
+
* workstream does not set one — which also means it overrides any
|
|
217
|
+
* `concurrency` placed in `defaultBullMQWorkerOptions`. Native BullMQ mode
|
|
218
|
+
* writes none, so BullMQ's own default of 1 applies there. Moving a queue
|
|
219
|
+
* between the two modes therefore changes how many jobs it runs at once by a
|
|
220
|
+
* factor of ten, with nothing in either configuration saying so.
|
|
221
|
+
*
|
|
222
|
+
* See `workerCount` above for the `workerCount × concurrency` product.
|
|
201
223
|
*/
|
|
202
|
-
workerCount?: number;
|
|
203
224
|
concurrency?: number;
|
|
204
225
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
226
|
+
* Rate-limit this workstream: at most `max` jobs start in any `duration`
|
|
227
|
+
* milliseconds. Works on open-source BullMQ and on BullMQ Pro.
|
|
228
|
+
*
|
|
229
|
+
* The limit is per queue, not per worker: every one of this workstream's
|
|
230
|
+
* workers, in every process running it, shares one counter kept in Redis, so
|
|
231
|
+
* `{ max: 1, duration: 1000 }` means one job per second for the workstream as
|
|
232
|
+
* a whole. `concurrency` caps how many jobs each worker runs at once;
|
|
233
|
+
* `rateLimit` caps how many may start per window across the whole workstream.
|
|
234
|
+
* For this workstream's workers it takes precedence over a global
|
|
235
|
+
* `defaultBullMQWorkerOptions.limiter`.
|
|
236
|
+
*
|
|
237
|
+
* A job on this workstream that is told to slow down (an HTTP 429, say) can
|
|
238
|
+
* throw `RateLimitedPsychicJob` from `@rvoh/psychic-workers/errors` to pause
|
|
239
|
+
* the whole workstream without burning a retry attempt; see that class for
|
|
240
|
+
* the pause semantics and for the `maxStartedAttempts` bound.
|
|
241
|
+
*
|
|
242
|
+
* A debounced job on this workstream must carry a delay long enough that it
|
|
243
|
+
* cannot enqueue faster than this limit starts jobs, or it is refused at
|
|
244
|
+
* enqueue: see `DelayedJobOpts.jobId`.
|
|
245
|
+
*
|
|
246
|
+
* `max` and `duration` are both required positive integers (`duration` in
|
|
247
|
+
* milliseconds): open-source BullMQ floors a fractional `duration` to 0ms
|
|
248
|
+
* (rate limiting nothing) and fails every job fetch on one past Redis's
|
|
249
|
+
* integer range. A `rateLimit` that reaches `connect()` without both fails
|
|
250
|
+
* `connect()` naming the workstream and the field, before any queue or worker
|
|
251
|
+
* is built.
|
|
252
|
+
*
|
|
253
|
+
* Implemented as BullMQ's worker `limiter` option, and on BullMQ Pro also as
|
|
254
|
+
* the workstream group's rate limit (unverified against an installed Pro
|
|
255
|
+
* build).
|
|
207
256
|
*/
|
|
208
257
|
rateLimit?: {
|
|
209
|
-
max
|
|
210
|
-
duration
|
|
258
|
+
max: number;
|
|
259
|
+
duration: number;
|
|
211
260
|
};
|
|
212
261
|
/**
|
|
213
262
|
* Optional redis connection. If not provided, the default background redis connection will be used.
|
|
@@ -1,10 +1,41 @@
|
|
|
1
|
+
import { Queue } from 'bullmq';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*
|
|
5
|
+
* resolves the queue's expected Redis name through `nameToRedisQueueName`,
|
|
6
|
+
* rather than hand-reconstructing a cluster hash tag or parallel-test suffix.
|
|
7
|
+
* `queue.opts.connection` is the same `Redis | Cluster` instance the queue was
|
|
8
|
+
* built with, which is why the cast is safe for every queue this package builds.
|
|
9
|
+
*/
|
|
10
|
+
export declare function queueNamesMatch(queue: Queue, compareQueueName: string): boolean;
|
|
1
11
|
export default class WorkerTestUtils {
|
|
2
12
|
static parallelTestSafeQueueName(queueName: string): string;
|
|
3
13
|
static work(opts?: TestWorkerWorkOffOpts): Promise<void>;
|
|
4
14
|
static workScheduled(opts?: TestWorkerScheduledWorkOffOpts): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* runs a delayed job in place. A `RateLimitedPsychicJob` thrown from a job on
|
|
17
|
+
* a queue whose workers carry no BullMQ `limiter` surfaces as the same
|
|
18
|
+
* misconfiguration error production would fail the job with; on a queue whose
|
|
19
|
+
* workers carry one, it propagates untranslated so the spec can assert on it.
|
|
20
|
+
*/
|
|
21
|
+
private static doScheduledWork;
|
|
5
22
|
static clean(): Promise<void>;
|
|
6
23
|
private static workOne;
|
|
7
|
-
|
|
24
|
+
/**
|
|
25
|
+
* runs one fetched job to completion or failure, mirroring what a real worker
|
|
26
|
+
* would do with a `RateLimitedPsychicJob`, then surfacing it so the spec goes
|
|
27
|
+
* red rather than looping:
|
|
28
|
+
*
|
|
29
|
+
* - on a queue whose workers carry no BullMQ `limiter`, the job is failed with
|
|
30
|
+
* the misconfiguration error production would fail it with (so, with the
|
|
31
|
+
* queue's `attempts` > 1, it lands in `delayed` for its retry, out of
|
|
32
|
+
* `active`, where `clean()` can reach it), and that error is rethrown
|
|
33
|
+
* - on a queue whose workers carry one, the job is moved back to the queue
|
|
34
|
+
* with no attempt counted (BullMQ's own rate-limit path), and the
|
|
35
|
+
* `RateLimitedPsychicJob` is rethrown
|
|
36
|
+
*
|
|
37
|
+
* Every other error only fails the job, as before.
|
|
38
|
+
*/
|
|
8
39
|
private static processJob;
|
|
9
40
|
}
|
|
10
41
|
interface TestWorkerWorkOffOpts {
|
|
@@ -29,14 +29,73 @@ export interface BackgroundJobData {
|
|
|
29
29
|
*/
|
|
30
30
|
globalName?: string;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* the delay to hold a job for and, when a `jobId` is provided, the debounce
|
|
34
|
+
* that delay drives.
|
|
35
|
+
*
|
|
36
|
+
* Calling a delayed background method repeatedly with the same `jobId`
|
|
37
|
+
* collapses those calls into a **single execution**. Each call slides the
|
|
38
|
+
* pending job's fire time further out, and the job runs once, after the last
|
|
39
|
+
* call, when the delay has finally elapsed without another call arriving.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* // ten calls in quick succession; the report is generated once,
|
|
43
|
+
* // ten seconds after the last of them
|
|
44
|
+
* await Report.backgroundWith({ delay: { seconds: 10, jobId: `report-${user.id}` } }, 'generate', user.id)
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* A delay object must carry at least one of `seconds`, `minutes`, `hours` or
|
|
48
|
+
* `days`. `{}` and `{ jobId: 'my-job' }` are compile errors, since a delay with
|
|
49
|
+
* no duration delays nothing and a `jobId` with no duration debounces
|
|
50
|
+
* nothing.
|
|
51
|
+
*/
|
|
52
|
+
export type DelayedJobOpts = AtLeastOneDelayedJobDuration & {
|
|
33
53
|
/**
|
|
34
|
-
* a
|
|
35
|
-
*
|
|
36
|
-
*
|
|
54
|
+
* a **deduplication key**, which debounces repeated calls: calls carrying the
|
|
55
|
+
* same `jobId` collapse into a single execution, which runs once the delay
|
|
56
|
+
* has elapsed without another call arriving. The window runs from the last
|
|
57
|
+
* call, not the first, so a burst is collapsed however long it lasts.
|
|
58
|
+
*
|
|
59
|
+
* Despite the name, this is not the BullMQ job id of the enqueued job, and
|
|
60
|
+
* `queue.getJob(jobId)` will not resolve the debounced job through it. BullMQ
|
|
61
|
+
* stores it as a separate Redis key; the matching read is
|
|
62
|
+
* `queue.getDeduplicationJobId(jobId)`.
|
|
63
|
+
*
|
|
64
|
+
* A delay carrying a `jobId` must be **at least three seconds**, and a
|
|
65
|
+
* shorter one is refused at enqueue.
|
|
66
|
+
*
|
|
67
|
+
* On a rate-limited workstream the delay must also clear the limiter's
|
|
68
|
+
* spacing: `delay - 1s >= duration / max`, so a workstream limited to one job
|
|
69
|
+
* a minute needs a 61-second delay. A delay that does not is refused at
|
|
70
|
+
* enqueue, naming the queue, both limiter numbers and a delay that would
|
|
71
|
+
* pass.
|
|
37
72
|
*/
|
|
38
73
|
jobId?: string;
|
|
39
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* `DelayedJobDuration`, but at least one field has to be there. Every field is
|
|
77
|
+
* optional on its own, so `{}` would otherwise compile and delay nothing.
|
|
78
|
+
* TypeScript has no "at least one of these" operator, so this spells out the
|
|
79
|
+
* four ways to satisfy it and joins them with `|`:
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* | { seconds: number; minutes?: number; hours?: number; days?: number }
|
|
83
|
+
* | { minutes: number; seconds?: number; hours?: number; days?: number }
|
|
84
|
+
* | { hours: number; seconds?: number; minutes?: number; days?: number }
|
|
85
|
+
* | { days: number; seconds?: number; minutes?: number; hours?: number }
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* A value has to match one of those, which means carrying that line's required
|
|
89
|
+
* field. `{ seconds: 30 }` matches the first. `{}` matches none, and neither
|
|
90
|
+
* does `{ jobId: 'my-job' }`.
|
|
91
|
+
*
|
|
92
|
+
* Not exported: it exists only to narrow `DelayedJobOpts`. `DelayedJobDuration`
|
|
93
|
+
* itself stays all-optional because it is also the parameter type of the shared
|
|
94
|
+
* `durationToSeconds` helper.
|
|
95
|
+
*/
|
|
96
|
+
type AtLeastOneDelayedJobDuration = {
|
|
97
|
+
[Field in keyof DelayedJobDuration]-?: Required<Pick<DelayedJobDuration, Field>> & Partial<Omit<DelayedJobDuration, Field>>;
|
|
98
|
+
}[keyof DelayedJobDuration];
|
|
40
99
|
export interface DelayedJobDuration {
|
|
41
100
|
seconds?: number;
|
|
42
101
|
minutes?: number;
|
|
@@ -45,6 +104,27 @@ export interface DelayedJobDuration {
|
|
|
45
104
|
}
|
|
46
105
|
export type JobTypes = 'BackgroundJobQueueFunctionJob' | 'BackgroundJobQueueStaticJob' | 'BackgroundJobQueueModelInstanceJob';
|
|
47
106
|
export type BackgroundQueuePriority = 'default' | 'urgent' | 'not_urgent' | 'last';
|
|
107
|
+
export interface BackgroundWithOpts {
|
|
108
|
+
/**
|
|
109
|
+
* an optional delay to hold off the job for a certain amount of
|
|
110
|
+
* time after it is entered into the queue. Accepts the same options
|
|
111
|
+
* as `backgroundWithDelay`, and must carry at least one of `seconds`,
|
|
112
|
+
* `minutes`, `hours` or `days`.
|
|
113
|
+
*
|
|
114
|
+
* Adding a `jobId` turns the delay into a **debounce**: repeated calls
|
|
115
|
+
* carrying the same `jobId` collapse into a single execution, which runs
|
|
116
|
+
* once the delay has elapsed without another call arriving. `jobId` is a
|
|
117
|
+
* deduplication key rather than a BullMQ job id.
|
|
118
|
+
*
|
|
119
|
+
* See {@link DelayedJobOpts.jobId}.
|
|
120
|
+
*/
|
|
121
|
+
delay?: DelayedJobOpts;
|
|
122
|
+
/**
|
|
123
|
+
* an optional priority. When provided, this overrides the priority
|
|
124
|
+
* set on the `backgroundJobConfig` of the service or model.
|
|
125
|
+
*/
|
|
126
|
+
priority?: BackgroundQueuePriority;
|
|
127
|
+
}
|
|
48
128
|
interface BaseBackgroundJobConfig {
|
|
49
129
|
priority?: BackgroundQueuePriority;
|
|
50
130
|
}
|
|
@@ -57,4 +137,20 @@ export interface QueueBackgroundJobConfig<T extends BaseScheduledService | BaseB
|
|
|
57
137
|
}
|
|
58
138
|
export type BackgroundJobConfig<T extends BaseScheduledService | BaseBackgroundedService> = Either<WorkstreamBackgroundJobConfig<T>, QueueBackgroundJobConfig<T>>;
|
|
59
139
|
export type PsychicBackgroundOptions = (PsychicBackgroundSimpleOptions & Partial<Record<Exclude<keyof PsychicBackgroundNativeBullMQOptions, keyof PsychicBackgroundSimpleOptions>, never>>) | (PsychicBackgroundNativeBullMQOptions & Partial<Record<Exclude<keyof PsychicBackgroundSimpleOptions, keyof PsychicBackgroundNativeBullMQOptions>, never>>);
|
|
140
|
+
/**
|
|
141
|
+
* @internal
|
|
142
|
+
*
|
|
143
|
+
* how a queue was configured, as far as the misconfiguration message needs to
|
|
144
|
+
* know in order to name the fix that applies to the worker that threw
|
|
145
|
+
*/
|
|
146
|
+
export interface WorkerQueueDescription {
|
|
147
|
+
/** simple (workstream) configuration or native BullMQ configuration */
|
|
148
|
+
mode: 'simple' | 'native';
|
|
149
|
+
/** the default workstream/queue, as opposed to a named one */
|
|
150
|
+
isDefaultQueue: boolean;
|
|
151
|
+
/** the workstream or queue name as configured (not the formatted Redis queue name) */
|
|
152
|
+
configuredName: string;
|
|
153
|
+
/** a workstream declared under `transitionalWorkstreams` */
|
|
154
|
+
transitional: boolean;
|
|
155
|
+
}
|
|
60
156
|
export {};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@rvoh/psychic-workers",
|
|
4
4
|
"description": "Background job system for Psychic applications",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.7.0",
|
|
6
6
|
"author": "RVO Health",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"ioredis": "^5.8.2"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@eslint/js": "^
|
|
64
|
+
"@eslint/js": "^10.0.1",
|
|
65
65
|
"@koa/cors": "^5.0.0",
|
|
66
66
|
"@koa/etag": "^5.0.2",
|
|
67
67
|
"@koa/router": "^15.4.0",
|
|
@@ -78,15 +78,15 @@
|
|
|
78
78
|
"@types/node": "^22.12.0",
|
|
79
79
|
"@types/pg": "^8",
|
|
80
80
|
"@types/supertest": "^6.0.3",
|
|
81
|
-
"@typescript-eslint/parser": "^8.
|
|
81
|
+
"@typescript-eslint/parser": "^8.67.0",
|
|
82
82
|
"bullmq": "^5.64.0",
|
|
83
|
-
"eslint": "^
|
|
83
|
+
"eslint": "^10.0.1",
|
|
84
84
|
"ioredis": "^5.8.2",
|
|
85
85
|
"koa": "^3.1.2",
|
|
86
86
|
"koa-bodyparser": "^4.4.1",
|
|
87
87
|
"koa-conditional-get": "^3.0.0",
|
|
88
|
-
"kysely": "^0.28.
|
|
89
|
-
"kysely-codegen": "
|
|
88
|
+
"kysely": "^0.28.17",
|
|
89
|
+
"kysely-codegen": "~0.20.0",
|
|
90
90
|
"luxon-jest-matchers": "^0.1.14",
|
|
91
91
|
"openapi-typescript": "^7.9.1",
|
|
92
92
|
"pg": "^8.13.1",
|
|
@@ -96,8 +96,9 @@
|
|
|
96
96
|
"tsx": "^4.20.6",
|
|
97
97
|
"typedoc": "^0.28.17",
|
|
98
98
|
"typescript": "^5.8.2",
|
|
99
|
-
"typescript-eslint": "^8.
|
|
100
|
-
"
|
|
99
|
+
"typescript-eslint": "^8.67.0",
|
|
100
|
+
"vite": "^7.3.6",
|
|
101
|
+
"vitest": "^4.1.11"
|
|
101
102
|
},
|
|
102
103
|
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
103
104
|
"dependencies": {
|