@c9up/bay 0.1.12 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -1
- package/dist/BayProvider.d.ts +55 -33
- package/dist/BayProvider.d.ts.map +1 -1
- package/dist/BayProvider.js +81 -10
- package/dist/BayProvider.js.map +1 -1
- package/dist/Job.d.ts +99 -0
- package/dist/Job.d.ts.map +1 -0
- package/dist/Job.js +78 -0
- package/dist/Job.js.map +1 -0
- package/dist/QueueManager.d.ts +147 -22
- package/dist/QueueManager.d.ts.map +1 -1
- package/dist/QueueManager.js +290 -52
- package/dist/QueueManager.js.map +1 -1
- package/dist/adapters.d.ts +68 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +56 -0
- package/dist/adapters.js.map +1 -0
- package/dist/augmentations.d.ts +28 -0
- package/dist/augmentations.d.ts.map +1 -0
- package/dist/augmentations.js +17 -0
- package/dist/augmentations.js.map +1 -0
- package/dist/configure.d.ts +19 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +48 -0
- package/dist/configure.js.map +1 -0
- package/dist/console/contract.d.ts +60 -0
- package/dist/console/contract.d.ts.map +1 -0
- package/dist/console/contract.js +36 -0
- package/dist/console/contract.js.map +1 -0
- package/dist/console/index.d.ts +29 -0
- package/dist/console/index.d.ts.map +1 -0
- package/dist/console/index.js +45 -0
- package/dist/console/index.js.map +1 -0
- package/dist/console/makeJob.d.ts +32 -0
- package/dist/console/makeJob.d.ts.map +1 -0
- package/dist/console/makeJob.js +118 -0
- package/dist/console/makeJob.js.map +1 -0
- package/dist/console/queueWork.d.ts +18 -0
- package/dist/console/queueWork.d.ts.map +1 -0
- package/dist/console/queueWork.js +58 -0
- package/dist/console/queueWork.js.map +1 -0
- package/dist/drivers/MemoryDriver.d.ts +14 -8
- package/dist/drivers/MemoryDriver.d.ts.map +1 -1
- package/dist/drivers/MemoryDriver.js +61 -7
- package/dist/drivers/MemoryDriver.js.map +1 -1
- package/dist/drivers/RedisDriver.d.ts +66 -8
- package/dist/drivers/RedisDriver.d.ts.map +1 -1
- package/dist/drivers/RedisDriver.js +257 -45
- package/dist/drivers/RedisDriver.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +43 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +105 -0
- package/dist/jobs.js.map +1 -0
- package/dist/nodeEnv.d.ts +16 -0
- package/dist/nodeEnv.d.ts.map +1 -0
- package/dist/nodeEnv.js +32 -0
- package/dist/nodeEnv.js.map +1 -0
- package/dist/quasar.d.ts +1 -1
- package/dist/quasar.js +1 -1
- package/dist/services/main.d.ts +5 -0
- package/dist/services/main.d.ts.map +1 -1
- package/dist/services/main.js +7 -0
- package/dist/services/main.js.map +1 -1
- package/dist/testing/FakeQueue.d.ts +15 -9
- package/dist/testing/FakeQueue.d.ts.map +1 -1
- package/dist/testing/FakeQueue.js +13 -3
- package/dist/testing/FakeQueue.js.map +1 -1
- package/package.json +9 -3
- package/src/BayProvider.ts +143 -25
- package/src/Job.ts +137 -0
- package/src/QueueManager.ts +454 -56
- package/src/adapters.ts +75 -0
- package/src/augmentations.ts +31 -0
- package/src/configure.ts +63 -0
- package/src/console/contract.ts +94 -0
- package/src/console/index.ts +68 -0
- package/src/console/makeJob.ts +139 -0
- package/src/console/queueWork.ts +70 -0
- package/src/drivers/MemoryDriver.ts +66 -14
- package/src/drivers/RedisDriver.ts +366 -63
- package/src/index.ts +35 -5
- package/src/jobs.ts +111 -0
- package/src/nodeEnv.ts +30 -0
- package/src/quasar.ts +1 -1
- package/src/services/main.ts +8 -0
- package/src/testing/FakeQueue.ts +25 -15
|
@@ -17,15 +17,39 @@
|
|
|
17
17
|
* { PX: ms }) does NOT satisfy this interface and would drop the lease TTL — it
|
|
18
18
|
* needs a thin adapter.
|
|
19
19
|
*/
|
|
20
|
+
import { DEFAULT_QUEUE } from "../Job.js";
|
|
21
|
+
import { inProduction } from "../nodeEnv.js";
|
|
22
|
+
import { queueOf } from "../QueueManager.js";
|
|
20
23
|
function isValidJob(obj) {
|
|
21
24
|
if (typeof obj !== "object" || obj === null)
|
|
22
25
|
return false;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
typeof
|
|
26
|
-
typeof
|
|
27
|
-
typeof
|
|
28
|
-
|
|
26
|
+
return (typeof Reflect.get(obj, "id") === "string" &&
|
|
27
|
+
typeof Reflect.get(obj, "name") === "string" &&
|
|
28
|
+
typeof Reflect.get(obj, "attempts") === "number" &&
|
|
29
|
+
typeof Reflect.get(obj, "maxAttempts") === "number" &&
|
|
30
|
+
typeof Reflect.get(obj, "status") === "string");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read a lease back. A value written by an older version of this driver is the
|
|
34
|
+
* raw job string on its own, with no owner — still usable for the one thing
|
|
35
|
+
* `#removeFromProcessing` needs it for.
|
|
36
|
+
*/
|
|
37
|
+
function readLease(stored) {
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(stored);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { raw: stored };
|
|
44
|
+
}
|
|
45
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
46
|
+
return { raw: stored };
|
|
47
|
+
const raw = Reflect.get(parsed, "raw");
|
|
48
|
+
const owner = Reflect.get(parsed, "owner");
|
|
49
|
+
if (typeof raw !== "string" || typeof owner !== "string") {
|
|
50
|
+
return { raw: stored };
|
|
51
|
+
}
|
|
52
|
+
return { owner, raw };
|
|
29
53
|
}
|
|
30
54
|
/**
|
|
31
55
|
* LMOVE (Redis 6.2+) is what makes pop() atomic. Warned once, when the client
|
|
@@ -33,13 +57,32 @@ function isValidJob(obj) {
|
|
|
33
57
|
* has no client to inspect yet.
|
|
34
58
|
*/
|
|
35
59
|
const warned = new WeakSet();
|
|
36
|
-
function
|
|
37
|
-
if (typeof client.lmove === "function"
|
|
60
|
+
function checkLmove(client, allowNonAtomicPop) {
|
|
61
|
+
if (typeof client.lmove === "function")
|
|
62
|
+
return;
|
|
63
|
+
// A queue's whole promise is that a job it accepted gets run. Without LMOVE
|
|
64
|
+
// the pop is `lpop` then `rpush`, and a crash between the two deletes the
|
|
65
|
+
// job from pending before it reaches processing: nothing recovers it,
|
|
66
|
+
// because nothing knows it existed. That is a different product, and in
|
|
67
|
+
// production it must be asked for rather than fallen into.
|
|
68
|
+
if (inProduction() && !allowNonAtomicPop) {
|
|
69
|
+
throw new Error("[bay] this Redis client has no LMOVE (Redis < 6.2), so pop() would be a non-atomic lpop+rpush — " +
|
|
70
|
+
"a crash between the two loses the in-flight job, turning at-least-once delivery into at-most-once.\n" +
|
|
71
|
+
" Upgrade to Redis 6.2 or later, or pass `allowNonAtomicPop: true` to state that losing a job is acceptable here.");
|
|
72
|
+
}
|
|
73
|
+
if (warned.has(client))
|
|
38
74
|
return;
|
|
39
75
|
warned.add(client);
|
|
76
|
+
// Said even when the deployment opted in: agreeing to lose a job once, in a
|
|
77
|
+
// config file, is not the same as being reminded that this process is
|
|
78
|
+
// running that way. The line has to be in the logs of the incident.
|
|
79
|
+
const optedIn = inProduction() && allowNonAtomicPop;
|
|
40
80
|
console.warn("[bay] RedisDriver: client lacks LMOVE (Redis <6.2). pop() falls back to " +
|
|
41
81
|
"a non-atomic lpop+rpush, downgrading delivery from at-least-once to " +
|
|
42
|
-
"at-most-once — a crash between the two commands loses the in-flight job."
|
|
82
|
+
"at-most-once — a crash between the two commands loses the in-flight job." +
|
|
83
|
+
(optedIn
|
|
84
|
+
? "\n Running this way in PRODUCTION because allowNonAtomicPop was set."
|
|
85
|
+
: ""));
|
|
43
86
|
}
|
|
44
87
|
/**
|
|
45
88
|
* A key prefix that ends in a separator.
|
|
@@ -67,7 +110,7 @@ export class RedisDriver {
|
|
|
67
110
|
return this.#resolved;
|
|
68
111
|
if (typeof this.#source !== "function") {
|
|
69
112
|
this.#resolved = this.#source;
|
|
70
|
-
|
|
113
|
+
checkLmove(this.#resolved, this.#allowNonAtomicPop);
|
|
71
114
|
return this.#resolved;
|
|
72
115
|
}
|
|
73
116
|
if (!this.#pending) {
|
|
@@ -75,7 +118,7 @@ export class RedisDriver {
|
|
|
75
118
|
this.#pending = Promise.resolve(resolver())
|
|
76
119
|
.then((client) => {
|
|
77
120
|
this.#resolved = client;
|
|
78
|
-
|
|
121
|
+
checkLmove(client, this.#allowNonAtomicPop);
|
|
79
122
|
return client;
|
|
80
123
|
})
|
|
81
124
|
// Cleared on failure too. Clearing only on success left the
|
|
@@ -93,13 +136,15 @@ export class RedisDriver {
|
|
|
93
136
|
// A client handed in directly can be checked now, so the warning keeps
|
|
94
137
|
// landing at construction as it always did. A named connection has no
|
|
95
138
|
// client yet — it is checked when the connection resolves.
|
|
96
|
-
if (typeof source !== "function")
|
|
97
|
-
|
|
139
|
+
if (typeof source !== "function") {
|
|
140
|
+
checkLmove(source, options?.allowNonAtomicPop ?? false);
|
|
141
|
+
}
|
|
98
142
|
// Normalised rather than documented: every key is built by concatenation
|
|
99
143
|
// (`${prefix}pending`), so a prefix without a trailing separator yields
|
|
100
144
|
// "myapppending" — unreadable, and able to collide with a neighbouring
|
|
101
145
|
// prefix. Nothing warned, because nothing failed.
|
|
102
146
|
this.#prefix = withSeparator(options?.prefix ?? "queue:");
|
|
147
|
+
this.#allowNonAtomicPop = options?.allowNonAtomicPop ?? false;
|
|
103
148
|
const visibilityTimeout = options?.visibilityTimeoutMs ?? 30_000;
|
|
104
149
|
// A non-positive / non-integer timeout makes pop()'s `SET … PX <ms>` fail
|
|
105
150
|
// on a real Redis; the catch then removes the job from `processing` and
|
|
@@ -109,44 +154,119 @@ export class RedisDriver {
|
|
|
109
154
|
throw new Error(`[bay] RedisDriver visibilityTimeoutMs must be a positive integer (ms), got ${visibilityTimeout}`);
|
|
110
155
|
}
|
|
111
156
|
this.#visibilityTimeout = visibilityTimeout;
|
|
157
|
+
const maxStalled = options?.maxStalledCount ?? 1;
|
|
158
|
+
if (!Number.isInteger(maxStalled) || maxStalled < 0) {
|
|
159
|
+
throw new Error(`[bay] RedisDriver maxStalledCount must be a non-negative integer, got ${maxStalled}`);
|
|
160
|
+
}
|
|
161
|
+
this.#maxStalledCount = maxStalled;
|
|
162
|
+
const maxFailed = options?.maxFailedJobs ?? 1000;
|
|
163
|
+
if (!Number.isInteger(maxFailed) || maxFailed < 0) {
|
|
164
|
+
throw new Error(`[bay] RedisDriver maxFailedJobs must be a non-negative integer, got ${maxFailed}`);
|
|
165
|
+
}
|
|
166
|
+
this.#maxFailedJobs = maxFailed;
|
|
112
167
|
}
|
|
113
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Renew a lease at half its length: two chances to be heard before the
|
|
170
|
+
* deadline, so one slow round-trip does not hand a running job to somebody
|
|
171
|
+
* else. Read by `QueueManager` while a handler runs.
|
|
172
|
+
*/
|
|
173
|
+
get renewIntervalMs() {
|
|
174
|
+
return Math.max(1, Math.floor(this.#visibilityTimeout / 2));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Where one queue's jobs wait.
|
|
178
|
+
*
|
|
179
|
+
* The default queue keeps the key it always had. Naming it
|
|
180
|
+
* `queue:default:pending` would have been tidier and would have orphaned
|
|
181
|
+
* every job already sitting in `queue:pending` at the moment of the upgrade
|
|
182
|
+
* — a silent loss, since nothing reads the old key afterwards.
|
|
183
|
+
*/
|
|
184
|
+
#pendingKey = (queue = DEFAULT_QUEUE) => queue === DEFAULT_QUEUE
|
|
185
|
+
? `${this.#prefix}pending`
|
|
186
|
+
: `${this.#prefix}q:${queue}:pending`;
|
|
187
|
+
#delayedKey = (queue = DEFAULT_QUEUE) => queue === DEFAULT_QUEUE
|
|
188
|
+
? `${this.#prefix}delayed`
|
|
189
|
+
: `${this.#prefix}q:${queue}:delayed`;
|
|
114
190
|
#processingKey = () => `${this.#prefix}processing`;
|
|
191
|
+
#allowNonAtomicPop = false;
|
|
192
|
+
#maxStalledCount = 1;
|
|
193
|
+
#maxFailedJobs = 1000;
|
|
194
|
+
/** This driver instance, as a lease owner. */
|
|
195
|
+
#workerId = crypto.randomUUID();
|
|
115
196
|
#failedKey = () => `${this.#prefix}failed`;
|
|
116
197
|
#leaseKey = (jobId) => `${this.#prefix}lease:${jobId}`;
|
|
117
198
|
async push(job) {
|
|
118
199
|
const client = await this.#client();
|
|
119
|
-
|
|
200
|
+
const queue = queueOf(job);
|
|
201
|
+
if (job.runAt !== undefined && job.runAt > Date.now()) {
|
|
202
|
+
if (!client.zadd) {
|
|
203
|
+
// Pushing it to the list instead would run it now, which is the
|
|
204
|
+
// one thing a delay exists to prevent.
|
|
205
|
+
throw new Error("This Redis client cannot hold a delayed job: it has no ZADD. " +
|
|
206
|
+
"Use a client with sorted-set commands (ioredis has them), or dispatch without `delay`.");
|
|
207
|
+
}
|
|
208
|
+
await client.zadd(this.#delayedKey(queue), job.runAt, JSON.stringify(job));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
await client.rpush(this.#pendingKey(queue), JSON.stringify(job));
|
|
120
212
|
}
|
|
121
|
-
async pop() {
|
|
213
|
+
async pop(queues = [DEFAULT_QUEUE]) {
|
|
122
214
|
const client = await this.#client();
|
|
123
215
|
let raw = null;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
raw
|
|
129
|
-
|
|
130
|
-
await client.rpush(this.#processingKey(), raw);
|
|
216
|
+
// In the order given, so a worker can say which queue it drains first.
|
|
217
|
+
for (const queue of queues) {
|
|
218
|
+
await this.#promoteDue(client, queue);
|
|
219
|
+
raw = await this.#take(client, queue);
|
|
220
|
+
if (raw !== null)
|
|
221
|
+
break;
|
|
131
222
|
}
|
|
132
223
|
if (!raw)
|
|
133
224
|
return null;
|
|
225
|
+
// Only a payload that can never be run is purged. Everything past this
|
|
226
|
+
// point is a REAL job that already sits in `processing`, and deleting
|
|
227
|
+
// it there is the one thing that loses it for good: it is gone from
|
|
228
|
+
// pending too, and recoverStale() scans processing, so nothing would
|
|
229
|
+
// ever find it again.
|
|
230
|
+
let parsed;
|
|
134
231
|
try {
|
|
135
|
-
|
|
136
|
-
if (!isValidJob(parsed)) {
|
|
137
|
-
// Malformed payload — purge from `processing` so it can't sit
|
|
138
|
-
// there indefinitely as a poison pill. recoverStale() also
|
|
139
|
-
// catches survivors but pop()'s own move is the primary path.
|
|
140
|
-
await client.lrem(this.#processingKey(), 1, raw);
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
await client.set(this.#leaseKey(parsed.id), raw, "PX", String(this.#visibilityTimeout));
|
|
144
|
-
return parsed;
|
|
232
|
+
parsed = JSON.parse(raw);
|
|
145
233
|
}
|
|
146
234
|
catch {
|
|
235
|
+
// A poison pill: unparseable, and it would sit in processing
|
|
236
|
+
// forever blocking nothing but wasting every recovery pass.
|
|
237
|
+
await client.lrem(this.#processingKey(), 1, raw);
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
if (!isValidJob(parsed)) {
|
|
147
241
|
await client.lrem(this.#processingKey(), 1, raw);
|
|
148
242
|
return null;
|
|
149
243
|
}
|
|
244
|
+
// A lease that cannot be written is a transient Redis failure, not a
|
|
245
|
+
// bad job. The error propagates and the job STAYS in processing with
|
|
246
|
+
// no lease, which is precisely the state recoverStale() puts back in
|
|
247
|
+
// pending — so the delivery guarantee survives the blip.
|
|
248
|
+
await client.set(this.#leaseKey(parsed.id), JSON.stringify({ owner: this.#workerId, raw }), "PX", String(this.#visibilityTimeout));
|
|
249
|
+
return parsed;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Say the job is still being worked on, and push its deadline back.
|
|
253
|
+
*
|
|
254
|
+
* Answers `false` when there is nothing left to renew — the lease expired
|
|
255
|
+
* and the job was recovered, or it was recovered and re-popped by another
|
|
256
|
+
* worker, whose claim this one must not extend.
|
|
257
|
+
*/
|
|
258
|
+
async renew(job) {
|
|
259
|
+
const client = await this.#client();
|
|
260
|
+
const key = this.#leaseKey(job.id);
|
|
261
|
+
const stored = await client.get(key);
|
|
262
|
+
if (stored === null)
|
|
263
|
+
return false;
|
|
264
|
+
const lease = readLease(stored);
|
|
265
|
+
if (lease.owner !== undefined && lease.owner !== this.#workerId) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
await client.set(key, stored, "PX", String(this.#visibilityTimeout));
|
|
269
|
+
return true;
|
|
150
270
|
}
|
|
151
271
|
async complete(job) {
|
|
152
272
|
const client = await this.#client();
|
|
@@ -159,14 +279,14 @@ export class RedisDriver {
|
|
|
159
279
|
await client.del(this.#leaseKey(job.id));
|
|
160
280
|
job.error = error;
|
|
161
281
|
job.status = "failed";
|
|
162
|
-
await
|
|
282
|
+
await this.#pushFailed(client, job);
|
|
163
283
|
}
|
|
164
284
|
async retry(job) {
|
|
165
285
|
const client = await this.#client();
|
|
166
286
|
await this.#removeFromProcessing(job);
|
|
167
287
|
await client.del(this.#leaseKey(job.id));
|
|
168
288
|
job.status = "pending";
|
|
169
|
-
await client.rpush(this.#pendingKey(), JSON.stringify(job));
|
|
289
|
+
await client.rpush(this.#pendingKey(queueOf(job)), JSON.stringify(job));
|
|
170
290
|
}
|
|
171
291
|
async recoverStale() {
|
|
172
292
|
const client = await this.#client();
|
|
@@ -188,29 +308,72 @@ export class RedisDriver {
|
|
|
188
308
|
continue;
|
|
189
309
|
}
|
|
190
310
|
const lease = await client.get(this.#leaseKey(parsed.id));
|
|
191
|
-
if (lease
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
311
|
+
if (lease !== null)
|
|
312
|
+
continue;
|
|
313
|
+
// The LREM is the claim, and its RESULT decides who acts. Two
|
|
314
|
+
// recovery passes overlapping — two workers, or one worker whose
|
|
315
|
+
// pass ran long — both read the same expired entry, and both used to
|
|
316
|
+
// push it back to pending: one job, delivered twice, from the
|
|
317
|
+
// mechanism that exists to make delivery reliable. Exactly one LREM
|
|
318
|
+
// can remove a given element, so exactly one pass continues past
|
|
319
|
+
// here. (A crash between this and the RPUSH below still loses the
|
|
320
|
+
// entry; closing that needs the whole pass in one server-side script,
|
|
321
|
+
// which is how upstream does it.)
|
|
322
|
+
const claimed = await client.lrem(this.#processingKey(), 1, raw);
|
|
323
|
+
if (claimed === 0)
|
|
324
|
+
continue;
|
|
325
|
+
// A stall is not an attempt: the worker died before the handler
|
|
326
|
+
// could fail, so `attempts` never moved and `maxAttempts` never
|
|
327
|
+
// applied. A job that kills whatever picks it up was therefore
|
|
328
|
+
// recovered forever, taking the queue with it. Counted separately,
|
|
329
|
+
// and bounded — upstream bounds the same thing with the same
|
|
330
|
+
// default, failing the job once it is exceeded.
|
|
331
|
+
const stalled = (parsed.stalledCount ?? 0) + 1;
|
|
332
|
+
if (stalled > this.#maxStalledCount) {
|
|
333
|
+
parsed.stalledCount = stalled;
|
|
334
|
+
parsed.status = "failed";
|
|
335
|
+
parsed.error = `Stalled ${stalled} time(s) without completing (maxStalledCount ${this.#maxStalledCount})`;
|
|
336
|
+
await this.#pushFailed(client, parsed);
|
|
337
|
+
continue;
|
|
196
338
|
}
|
|
339
|
+
parsed.stalledCount = stalled;
|
|
340
|
+
parsed.status = "pending";
|
|
341
|
+
// Back to the queue it came from, not to the default one: a recovered
|
|
342
|
+
// job whose queue nobody serves would never run again.
|
|
343
|
+
await client.rpush(this.#pendingKey(queueOf(parsed)), JSON.stringify(parsed));
|
|
344
|
+
recovered++;
|
|
197
345
|
}
|
|
198
346
|
return recovered;
|
|
199
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* File a job as failed, keeping the list to `maxFailedJobs`.
|
|
350
|
+
*
|
|
351
|
+
* Unbounded, the failed list is a leak with no ceiling and no owner: nothing
|
|
352
|
+
* trims it, and `failed()` reads all of it in one LRANGE. The memory driver
|
|
353
|
+
* has capped its own at a thousand from the start; this is the same cap on
|
|
354
|
+
* the driver where the list actually survives a restart.
|
|
355
|
+
*/
|
|
356
|
+
async #pushFailed(client, job) {
|
|
357
|
+
await client.rpush(this.#failedKey(), JSON.stringify(job));
|
|
358
|
+
if (this.#maxFailedJobs === 0 || !client.ltrim)
|
|
359
|
+
return;
|
|
360
|
+
await client.ltrim(this.#failedKey(), -this.#maxFailedJobs, -1);
|
|
361
|
+
}
|
|
200
362
|
/**
|
|
201
363
|
* Remove the entry for `job` from the processing list. The string in
|
|
202
364
|
* Redis is whatever pop() pushed, but QueueManager mutates `job` after
|
|
203
365
|
* pop returns (attempts++, status="processing", processedAt, then
|
|
204
366
|
* completed/failed/pending). LREM-ing on `JSON.stringify(job)` would
|
|
205
|
-
* therefore miss every real-world entry. Use the lease —
|
|
206
|
-
* exact raw string
|
|
367
|
+
* therefore miss every real-world entry. Use the lease — which carries
|
|
368
|
+
* the exact raw string pop() moved — and fall back to a list scan when
|
|
207
369
|
* the lease has expired (e.g. recoverStale already handled it).
|
|
208
370
|
*/
|
|
209
371
|
async #removeFromProcessing(job) {
|
|
210
372
|
const client = await this.#client();
|
|
211
373
|
const stored = await client.get(this.#leaseKey(job.id));
|
|
212
374
|
if (stored !== null) {
|
|
213
|
-
const
|
|
375
|
+
const { raw } = readLease(stored);
|
|
376
|
+
const removed = await client.lrem(this.#processingKey(), 1, raw);
|
|
214
377
|
if (removed > 0)
|
|
215
378
|
return;
|
|
216
379
|
}
|
|
@@ -246,9 +409,58 @@ export class RedisDriver {
|
|
|
246
409
|
})
|
|
247
410
|
.filter((j) => j !== null);
|
|
248
411
|
}
|
|
249
|
-
|
|
412
|
+
/**
|
|
413
|
+
* How many jobs are waiting on `queue` — its list plus its delayed set.
|
|
414
|
+
*
|
|
415
|
+
* A delayed job is queued; it is simply not due. Counting only the list
|
|
416
|
+
* reported an empty queue to anything draining one before shutdown.
|
|
417
|
+
*/
|
|
418
|
+
async size(queue = DEFAULT_QUEUE) {
|
|
250
419
|
const client = await this.#client();
|
|
251
|
-
|
|
420
|
+
const waiting = await client.llen(this.#pendingKey(queue));
|
|
421
|
+
const delayed = client.zcard
|
|
422
|
+
? await client.zcard(this.#delayedKey(queue))
|
|
423
|
+
: 0;
|
|
424
|
+
return waiting + delayed;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Move `queue`'s due jobs out of the delayed set and onto its list.
|
|
428
|
+
*
|
|
429
|
+
* `ZREM` is the claim: two workers can read the same due entry, and only
|
|
430
|
+
* the one whose removal returns 1 owns it. Without that the job is pushed
|
|
431
|
+
* onto the list once per worker that saw it.
|
|
432
|
+
*/
|
|
433
|
+
async #promoteDue(client, queue) {
|
|
434
|
+
if (!client.zrangebyscore || !client.zrem)
|
|
435
|
+
return;
|
|
436
|
+
const due = await client.zrangebyscore(this.#delayedKey(queue), 0, Date.now(), "LIMIT", "0", "100");
|
|
437
|
+
for (const raw of due) {
|
|
438
|
+
const claimed = await client.zrem(this.#delayedKey(queue), raw);
|
|
439
|
+
if (claimed !== 1)
|
|
440
|
+
continue;
|
|
441
|
+
let parsed;
|
|
442
|
+
try {
|
|
443
|
+
parsed = JSON.parse(raw);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
// Already removed from the set; there is nothing runnable to push.
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (!isValidJob(parsed))
|
|
450
|
+
continue;
|
|
451
|
+
parsed.runAt = undefined;
|
|
452
|
+
await client.rpush(this.#pendingKey(queue), JSON.stringify(parsed));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/** Take the head of one queue, claiming it in `processing`. */
|
|
456
|
+
async #take(client, queue) {
|
|
457
|
+
if (client.lmove) {
|
|
458
|
+
return client.lmove(this.#pendingKey(queue), this.#processingKey(), "LEFT", "RIGHT");
|
|
459
|
+
}
|
|
460
|
+
const raw = await client.lpop(this.#pendingKey(queue));
|
|
461
|
+
if (raw)
|
|
462
|
+
await client.rpush(this.#processingKey(), raw);
|
|
463
|
+
return raw;
|
|
252
464
|
}
|
|
253
465
|
}
|
|
254
466
|
//# sourceMappingURL=RedisDriver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisDriver.js","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RedisDriver.js","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @c9up/bay — Background job queue for the Ream framework.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* A job is a class: it carries its own name, its options and the type of the
|
|
5
|
+
* payload it reads, and `dispatch(SomeJob, payload)` takes it. Named queues,
|
|
6
|
+
* `delay`, `timeout` and worker `concurrency` come from the same declaration.
|
|
5
7
|
*
|
|
6
|
-
*
|
|
8
|
+
* Dispatch/process/retry/fail, with pluggable drivers (Memory, Redis).
|
|
7
9
|
*/
|
|
8
|
-
export type
|
|
10
|
+
export { type AdapterFactory, drivers, type QueueStoreFactory, stores, } from "./adapters.js";
|
|
11
|
+
import "./augmentations.js";
|
|
12
|
+
export type { BayAppContext, BayConfigStore, BayContainer, BayProviderConfig, } from "./BayProvider.js";
|
|
9
13
|
export { MemoryDriver } from "./drivers/MemoryDriver.js";
|
|
10
14
|
export type { RedisClient } from "./drivers/RedisDriver.js";
|
|
11
15
|
export { RedisDriver } from "./drivers/RedisDriver.js";
|
|
12
|
-
export type
|
|
13
|
-
export {
|
|
16
|
+
export { DEFAULT_QUEUE, type Duration, isJobClass, Job, type JobClass, type JobOptions, } from "./Job.js";
|
|
17
|
+
export type { DispatchOptions, JobHandler, JobRecord, QueueDriver, WorkerOptions, } from "./QueueManager.js";
|
|
18
|
+
export { QueueManager, queueOf } from "./QueueManager.js";
|
|
14
19
|
import type { BayProviderConfig } from "./BayProvider.js";
|
|
15
20
|
/**
|
|
16
21
|
* Author-time config helper for `config/queue.ts` — AdonisJS `defineConfig`
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACN,KAAK,cAAc,EACnB,OAAO,EACP,KAAK,iBAAiB,EACtB,MAAM,GACN,MAAM,eAAe,CAAC;AAEvB,OAAO,oBAAoB,CAAC;AAE5B,YAAY,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EACN,aAAa,EACb,KAAK,QAAQ,EACb,UAAU,EACV,GAAG,EACH,KAAK,QAAQ,EACb,KAAK,UAAU,GACf,MAAM,UAAU,CAAC;AAClB,YAAY,EACX,eAAe,EACf,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEtE;AACD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @c9up/bay — Background job queue for the Ream framework.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* A job is a class: it carries its own name, its options and the type of the
|
|
5
|
+
* payload it reads, and `dispatch(SomeJob, payload)` takes it. Named queues,
|
|
6
|
+
* `delay`, `timeout` and worker `concurrency` come from the same declaration.
|
|
5
7
|
*
|
|
6
|
-
*
|
|
8
|
+
* Dispatch/process/retry/fail, with pluggable drivers (Memory, Redis).
|
|
7
9
|
*/
|
|
10
|
+
export { drivers, stores, } from "./adapters.js";
|
|
11
|
+
import "./augmentations.js";
|
|
8
12
|
export { MemoryDriver } from "./drivers/MemoryDriver.js";
|
|
9
13
|
export { RedisDriver } from "./drivers/RedisDriver.js";
|
|
10
|
-
export {
|
|
14
|
+
export { DEFAULT_QUEUE, isJobClass, Job, } from "./Job.js";
|
|
15
|
+
export { QueueManager, queueOf } from "./QueueManager.js";
|
|
11
16
|
/**
|
|
12
17
|
* Author-time config helper for `config/queue.ts` — AdonisJS `defineConfig`
|
|
13
18
|
* parity. Identity at runtime; the generic preserves literal types for inference.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEN,OAAO,EAEP,MAAM,GACN,MAAM,eAAe,CAAC;AAEvB,OAAO,oBAAoB,CAAC;AAQ5B,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EACN,aAAa,EAEb,UAAU,EACV,GAAG,GAGH,MAAM,UAAU,CAAC;AAQlB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAI1D;;;GAGG;AACH,MAAM,UAAU,YAAY,CAA8B,MAAS;IAClE,OAAO,MAAM,CAAC;AACf,CAAC;AACD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/jobs.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding the job classes an application wrote.
|
|
3
|
+
*
|
|
4
|
+
* A job class carries its own name, and a worker resolves a queued record by
|
|
5
|
+
* that name — so the worker process has to have imported the class. Written by
|
|
6
|
+
* hand that is a registration list to keep in step with a directory:
|
|
7
|
+
*
|
|
8
|
+
* queue.registerJob(SendEmail)
|
|
9
|
+
* queue.registerJob(SendInvoice) // …and the one nobody added
|
|
10
|
+
*
|
|
11
|
+
* `locations` in `config/queue.ts` is the directory instead. Every module under
|
|
12
|
+
* it is imported once at boot, and a default export that is a job class is
|
|
13
|
+
* registered under its own name.
|
|
14
|
+
*
|
|
15
|
+
* Directories, not globs. `'./app/jobs/**\/*.{ts,js}'` — the spelling upstream's
|
|
16
|
+
* config uses — is accepted and read as the directory it starts with, so a
|
|
17
|
+
* config copied from there works; bay ships no glob engine and adding a
|
|
18
|
+
* dependency for one path shape is not worth it.
|
|
19
|
+
*/
|
|
20
|
+
import { type JobClass } from "./Job.js";
|
|
21
|
+
/** Where `make:job` writes, and where discovery looks when nothing is declared. */
|
|
22
|
+
export declare const DEFAULT_JOBS_DIR = "app/jobs";
|
|
23
|
+
/** @internal Told by the provider what the config declared. */
|
|
24
|
+
export declare function setJobsDir(dir: string): void;
|
|
25
|
+
/** Where job files live — the first `locations` entry, or the default. */
|
|
26
|
+
export declare function getJobsDir(): string;
|
|
27
|
+
/**
|
|
28
|
+
* The directory a `locations` entry names.
|
|
29
|
+
*
|
|
30
|
+
* Everything from the first glob character on is dropped: `app/jobs/** /*.ts`
|
|
31
|
+
* and `app/jobs` name the same directory, and the walk below is recursive
|
|
32
|
+
* either way.
|
|
33
|
+
*/
|
|
34
|
+
export declare function directoryOf(location: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Import every module under `locations` and return the job classes they
|
|
37
|
+
* default-export.
|
|
38
|
+
*
|
|
39
|
+
* A module that throws on import is reported and skipped: one unfinished job
|
|
40
|
+
* file must not stop the worker from running every other job.
|
|
41
|
+
*/
|
|
42
|
+
export declare function discoverJobs(locations: readonly string[]): Promise<JobClass[]>;
|
|
43
|
+
//# sourceMappingURL=jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAErD,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAI3C,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpD;AA6BD;;;;;;GAMG;AACH,wBAAsB,YAAY,CACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC1B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAqBrB"}
|