@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.
Files changed (90) hide show
  1. package/README.md +172 -1
  2. package/dist/BayProvider.d.ts +55 -33
  3. package/dist/BayProvider.d.ts.map +1 -1
  4. package/dist/BayProvider.js +81 -10
  5. package/dist/BayProvider.js.map +1 -1
  6. package/dist/Job.d.ts +99 -0
  7. package/dist/Job.d.ts.map +1 -0
  8. package/dist/Job.js +78 -0
  9. package/dist/Job.js.map +1 -0
  10. package/dist/QueueManager.d.ts +147 -22
  11. package/dist/QueueManager.d.ts.map +1 -1
  12. package/dist/QueueManager.js +290 -52
  13. package/dist/QueueManager.js.map +1 -1
  14. package/dist/adapters.d.ts +68 -0
  15. package/dist/adapters.d.ts.map +1 -0
  16. package/dist/adapters.js +56 -0
  17. package/dist/adapters.js.map +1 -0
  18. package/dist/augmentations.d.ts +28 -0
  19. package/dist/augmentations.d.ts.map +1 -0
  20. package/dist/augmentations.js +17 -0
  21. package/dist/augmentations.js.map +1 -0
  22. package/dist/configure.d.ts +19 -0
  23. package/dist/configure.d.ts.map +1 -0
  24. package/dist/configure.js +48 -0
  25. package/dist/configure.js.map +1 -0
  26. package/dist/console/contract.d.ts +60 -0
  27. package/dist/console/contract.d.ts.map +1 -0
  28. package/dist/console/contract.js +36 -0
  29. package/dist/console/contract.js.map +1 -0
  30. package/dist/console/index.d.ts +29 -0
  31. package/dist/console/index.d.ts.map +1 -0
  32. package/dist/console/index.js +45 -0
  33. package/dist/console/index.js.map +1 -0
  34. package/dist/console/makeJob.d.ts +32 -0
  35. package/dist/console/makeJob.d.ts.map +1 -0
  36. package/dist/console/makeJob.js +118 -0
  37. package/dist/console/makeJob.js.map +1 -0
  38. package/dist/console/queueWork.d.ts +18 -0
  39. package/dist/console/queueWork.d.ts.map +1 -0
  40. package/dist/console/queueWork.js +58 -0
  41. package/dist/console/queueWork.js.map +1 -0
  42. package/dist/drivers/MemoryDriver.d.ts +14 -8
  43. package/dist/drivers/MemoryDriver.d.ts.map +1 -1
  44. package/dist/drivers/MemoryDriver.js +61 -7
  45. package/dist/drivers/MemoryDriver.js.map +1 -1
  46. package/dist/drivers/RedisDriver.d.ts +66 -8
  47. package/dist/drivers/RedisDriver.d.ts.map +1 -1
  48. package/dist/drivers/RedisDriver.js +257 -45
  49. package/dist/drivers/RedisDriver.js.map +1 -1
  50. package/dist/index.d.ts +10 -5
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +8 -3
  53. package/dist/index.js.map +1 -1
  54. package/dist/jobs.d.ts +43 -0
  55. package/dist/jobs.d.ts.map +1 -0
  56. package/dist/jobs.js +105 -0
  57. package/dist/jobs.js.map +1 -0
  58. package/dist/nodeEnv.d.ts +16 -0
  59. package/dist/nodeEnv.d.ts.map +1 -0
  60. package/dist/nodeEnv.js +32 -0
  61. package/dist/nodeEnv.js.map +1 -0
  62. package/dist/quasar.d.ts +1 -1
  63. package/dist/quasar.js +1 -1
  64. package/dist/services/main.d.ts +5 -0
  65. package/dist/services/main.d.ts.map +1 -1
  66. package/dist/services/main.js +7 -0
  67. package/dist/services/main.js.map +1 -1
  68. package/dist/testing/FakeQueue.d.ts +15 -9
  69. package/dist/testing/FakeQueue.d.ts.map +1 -1
  70. package/dist/testing/FakeQueue.js +13 -3
  71. package/dist/testing/FakeQueue.js.map +1 -1
  72. package/package.json +9 -3
  73. package/src/BayProvider.ts +143 -25
  74. package/src/Job.ts +137 -0
  75. package/src/QueueManager.ts +454 -56
  76. package/src/adapters.ts +75 -0
  77. package/src/augmentations.ts +31 -0
  78. package/src/configure.ts +63 -0
  79. package/src/console/contract.ts +94 -0
  80. package/src/console/index.ts +68 -0
  81. package/src/console/makeJob.ts +139 -0
  82. package/src/console/queueWork.ts +70 -0
  83. package/src/drivers/MemoryDriver.ts +66 -14
  84. package/src/drivers/RedisDriver.ts +366 -63
  85. package/src/index.ts +35 -5
  86. package/src/jobs.ts +111 -0
  87. package/src/nodeEnv.ts +30 -0
  88. package/src/quasar.ts +1 -1
  89. package/src/services/main.ts +8 -0
  90. package/src/testing/FakeQueue.ts +25 -15
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeJob.js","sourceRoot":"","sources":["../../src/console/makeJob.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `queue:work` — run the worker that takes jobs off the queue.
3
+ *
4
+ * The command a deployment runs as its own process, beside the HTTP one:
5
+ *
6
+ * ream queue:work
7
+ * ream queue:work --queue=emails,notifications
8
+ * ream queue:work --concurrency=10
9
+ *
10
+ * It stays alive on purpose — `staysAlive` — and the loop it starts is the
11
+ * application's, so a SIGTERM reaches `BayProvider.shutdown()`, which stops the
12
+ * worker and lets the job in flight finish rather than dropping it.
13
+ */
14
+ import { type BayCommandClass } from "./contract.js";
15
+ /** Split `--queue=a,b` into names, dropping the empties a trailing comma makes. */
16
+ export declare function parseQueues(value: string | undefined): string[] | undefined;
17
+ export declare function queueWorkCommand(): BayCommandClass;
18
+ //# sourceMappingURL=queueWork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queueWork.d.ts","sourceRoot":"","sources":["../../src/console/queueWork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,eAAe,EAAQ,MAAM,eAAe,CAAC;AAE3D,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAO3E;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CA0ClD"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * `queue:work` — run the worker that takes jobs off the queue.
3
+ *
4
+ * The command a deployment runs as its own process, beside the HTTP one:
5
+ *
6
+ * ream queue:work
7
+ * ream queue:work --queue=emails,notifications
8
+ * ream queue:work --concurrency=10
9
+ *
10
+ * It stays alive on purpose — `staysAlive` — and the loop it starts is the
11
+ * application's, so a SIGTERM reaches `BayProvider.shutdown()`, which stops the
12
+ * worker and lets the job in flight finish rather than dropping it.
13
+ */
14
+ import { getQueue } from "../services/main.js";
15
+ import { flag } from "./contract.js";
16
+ /** Split `--queue=a,b` into names, dropping the empties a trailing comma makes. */
17
+ export function parseQueues(value) {
18
+ if (value === undefined)
19
+ return undefined;
20
+ const names = value
21
+ .split(",")
22
+ .map((name) => name.trim())
23
+ .filter((name) => name.length > 0);
24
+ return names.length > 0 ? names : undefined;
25
+ }
26
+ export function queueWorkCommand() {
27
+ return class QueueWork {
28
+ static commandName = "queue:work";
29
+ static description = "Process queued jobs until the process is stopped";
30
+ // The worker needs the container: the queue it drains is the one the
31
+ // provider booted, with the driver the config named.
32
+ static options = { startApp: true, staysAlive: true };
33
+ static flags = [
34
+ flag("queue", "string", {
35
+ description: "Comma-separated queues to serve, in order (default: the default queue)",
36
+ }),
37
+ flag("concurrency", "number", {
38
+ description: "How many jobs to run at once (default: 1)",
39
+ }),
40
+ ];
41
+ async run() {
42
+ const manager = getQueue();
43
+ if (!manager) {
44
+ // Naming the wiring beats a stack trace out of the service proxy:
45
+ // the usual cause is a project that never added the provider.
46
+ throw new Error("[bay] queue:work found no queue. Add `() => import('@c9up/bay/provider')` " +
47
+ "to the providers in reamrc.ts, or call setQueue(myQueue) at boot.");
48
+ }
49
+ const queues = parseQueues(this.queue);
50
+ process.stdout.write(`[bay] worker started — queues: ${(queues ?? ["default"]).join(", ")}, concurrency: ${this.concurrency ?? 1}\n`);
51
+ await manager.work({
52
+ queues,
53
+ concurrency: this.concurrency,
54
+ });
55
+ }
56
+ };
57
+ }
58
+ //# sourceMappingURL=queueWork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queueWork.js","sourceRoot":"","sources":["../../src/console/queueWork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAwB,IAAI,EAAE,MAAM,eAAe,CAAC;AAE3D,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,KAAyB;IACpD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAG,KAAK;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC/B,OAAO,MAAM,SAAS;QACrB,MAAM,CAAC,WAAW,GAAG,YAAY,CAAC;QAClC,MAAM,CAAC,WAAW,GAAG,kDAAkD,CAAC;QACxE,qEAAqE;QACrE,qDAAqD;QACrD,MAAM,CAAC,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACtD,MAAM,CAAC,KAAK,GAAG;YACd,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE;gBACvB,WAAW,EACV,wEAAwE;aACzE,CAAC;YACF,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE;gBAC7B,WAAW,EAAE,2CAA2C;aACxD,CAAC;SACF,CAAC;QAKF,KAAK,CAAC,GAAG;YACR,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,kEAAkE;gBAClE,8DAA8D;gBAC9D,MAAM,IAAI,KAAK,CACd,4EAA4E;oBAC3E,mEAAmE,CACpE,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,kCAAkC,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAC/G,CAAC;YAEF,MAAM,OAAO,CAAC,IAAI,CAAC;gBAClB,MAAM;gBACN,WAAW,EAAE,IAAI,CAAC,WAAW;aAC7B,CAAC,CAAC;QACJ,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -1,18 +1,24 @@
1
1
  /**
2
- * Memory queue driver — in-process queue for development.
2
+ * Memory queue driver — in-process queue for development and tests.
3
3
  */
4
- import type { Job, QueueDriver } from "../QueueManager.js";
4
+ import { type JobRecord, type QueueDriver } from "../QueueManager.js";
5
5
  export declare class MemoryDriver implements QueueDriver {
6
6
  #private;
7
7
  constructor(options?: {
8
8
  maxFailedJobs?: number;
9
9
  });
10
- push(job: Job): Promise<void>;
11
- pop(): Promise<Job | null>;
12
- fail(job: Job, error: string): Promise<void>;
13
- complete(_job: Job): Promise<void>;
14
- retry(job: Job): Promise<void>;
15
- failed(): Promise<Job[]>;
10
+ push(job: JobRecord): Promise<void>;
11
+ pop(queues?: readonly string[]): Promise<JobRecord | null>;
12
+ fail(job: JobRecord, error: string): Promise<void>;
13
+ complete(_job: JobRecord): Promise<void>;
14
+ retry(job: JobRecord): Promise<void>;
15
+ failed(): Promise<JobRecord[]>;
16
+ /**
17
+ * Everything waiting, across every queue — a delayed job included.
18
+ *
19
+ * It is queued; it is simply not due. Leaving it out would report an empty
20
+ * queue to anything draining one before shutdown.
21
+ */
16
22
  size(): Promise<number>;
17
23
  }
18
24
  //# sourceMappingURL=MemoryDriver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE3D,qBAAa,YAAa,YAAW,WAAW;;gBAKnC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;IAI1C,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7B,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAI1B,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9B,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAIxB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAG7B"}
1
+ {"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAW,MAAM,oBAAoB,CAAC;AAE/E,qBAAa,YAAa,YAAW,WAAW;;gBAcnC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;IAwB1C,IAAI,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IASnC,GAAG,CACR,MAAM,GAAE,SAAS,MAAM,EAAoB,GACzC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAWtB,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASlD,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpC,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpC;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAK7B"}
@@ -1,18 +1,63 @@
1
1
  /**
2
- * Memory queue driver — in-process queue for development.
2
+ * Memory queue driver — in-process queue for development and tests.
3
3
  */
4
+ import { DEFAULT_QUEUE } from "../Job.js";
5
+ import { queueOf } from "../QueueManager.js";
4
6
  export class MemoryDriver {
5
- #pending = [];
7
+ /** One list per named queue, created on first use. */
8
+ #pending = new Map();
9
+ /**
10
+ * Jobs whose `runAt` has not arrived, oldest deadline first.
11
+ *
12
+ * Kept apart from the queues rather than filtered on the way out: a delayed
13
+ * job at the head of a list would otherwise be skipped over on every poll,
14
+ * and a queue whose head is not due would look empty while it is not.
15
+ */
16
+ #delayed = [];
6
17
  #failedJobs = [];
7
18
  #maxFailedJobs;
8
19
  constructor(options) {
9
20
  this.#maxFailedJobs = options?.maxFailedJobs ?? 1000;
10
21
  }
22
+ #queue(name) {
23
+ const existing = this.#pending.get(name);
24
+ if (existing !== undefined)
25
+ return existing;
26
+ const created = [];
27
+ this.#pending.set(name, created);
28
+ return created;
29
+ }
30
+ /** Move everything whose delay has elapsed into its queue. */
31
+ #promoteDue(now = Date.now()) {
32
+ if (this.#delayed.length === 0)
33
+ return;
34
+ const due = this.#delayed.filter((job) => (job.runAt ?? 0) <= now);
35
+ if (due.length === 0)
36
+ return;
37
+ this.#delayed = this.#delayed.filter((job) => (job.runAt ?? 0) > now);
38
+ for (const job of due) {
39
+ job.runAt = undefined;
40
+ this.#queue(queueOf(job)).push(job);
41
+ }
42
+ }
11
43
  async push(job) {
12
- this.#pending.push(job);
44
+ if (job.runAt !== undefined && job.runAt > Date.now()) {
45
+ this.#delayed.push(job);
46
+ this.#delayed.sort((a, b) => (a.runAt ?? 0) - (b.runAt ?? 0));
47
+ return;
48
+ }
49
+ this.#queue(queueOf(job)).push(job);
13
50
  }
14
- async pop() {
15
- return this.#pending.shift() ?? null;
51
+ async pop(queues = [DEFAULT_QUEUE]) {
52
+ this.#promoteDue();
53
+ // In the order given: naming `['critical', 'default']` is how a worker
54
+ // says which queue it would rather drain first.
55
+ for (const name of queues) {
56
+ const next = this.#pending.get(name)?.shift();
57
+ if (next !== undefined)
58
+ return next;
59
+ }
60
+ return null;
16
61
  }
17
62
  async fail(job, error) {
18
63
  job.error = error;
@@ -27,13 +72,22 @@ export class MemoryDriver {
27
72
  }
28
73
  async retry(job) {
29
74
  job.status = "pending";
30
- this.#pending.push(job);
75
+ this.#queue(queueOf(job)).push(job);
31
76
  }
32
77
  async failed() {
33
78
  return [...this.#failedJobs];
34
79
  }
80
+ /**
81
+ * Everything waiting, across every queue — a delayed job included.
82
+ *
83
+ * It is queued; it is simply not due. Leaving it out would report an empty
84
+ * queue to anything draining one before shutdown.
85
+ */
35
86
  async size() {
36
- return this.#pending.length;
87
+ let total = this.#delayed.length;
88
+ for (const jobs of this.#pending.values())
89
+ total += jobs.length;
90
+ return total;
37
91
  }
38
92
  }
39
93
  //# sourceMappingURL=MemoryDriver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryDriver.js","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,OAAO,YAAY;IACxB,QAAQ,GAAU,EAAE,CAAC;IACrB,WAAW,GAAU,EAAE,CAAC;IACxB,cAAc,CAAS;IAEvB,YAAY,OAAoC;QAC/C,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,aAAa,IAAI,IAAI,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAQ;QAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,GAAG;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAQ,EAAE,KAAa;QACjC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QAClB,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACnD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3E,CAAC;IACF,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAS;QACvB,kCAAkC;IACnC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAQ;QACnB,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,MAAM;QACX,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC7B,CAAC;CACD"}
1
+ {"version":3,"file":"MemoryDriver.js","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"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"}
@@ -17,17 +17,32 @@
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 type { Job, QueueDriver } from "../QueueManager.js";
20
+ import { type JobRecord, type QueueDriver } from "../QueueManager.js";
21
21
  export interface RedisClient {
22
22
  rpush(key: string, ...values: string[]): Promise<number>;
23
23
  lpop(key: string): Promise<string | null>;
24
24
  lmove?(source: string, destination: string, from: "LEFT" | "RIGHT", to: "LEFT" | "RIGHT"): Promise<string | null>;
25
25
  lrem(key: string, count: number, element: string): Promise<number>;
26
+ /**
27
+ * Optional, like `lmove`. Present on ioredis; without it the failed list
28
+ * simply keeps its entries, which is what this driver did before.
29
+ */
30
+ ltrim?(key: string, start: number, stop: number): Promise<string>;
26
31
  llen(key: string): Promise<number>;
27
32
  lrange(key: string, start: number, stop: number): Promise<string[]>;
28
33
  del(key: string): Promise<number>;
29
34
  set(key: string, value: string, ...args: string[]): Promise<string | null>;
30
35
  get(key: string): Promise<string | null>;
36
+ /**
37
+ * Sorted-set commands, for delayed jobs. Optional like `lmove`: a client
38
+ * without them can still run a queue, and `push` refuses a job carrying a
39
+ * `delay` rather than running it early — which is the one thing a delay
40
+ * must not do.
41
+ */
42
+ zadd?(key: string, score: number, member: string): Promise<number | string>;
43
+ zrangebyscore?(key: string, min: number | string, max: number | string, ...args: string[]): Promise<string[]>;
44
+ zrem?(key: string, ...members: string[]): Promise<number>;
45
+ zcard?(key: string): Promise<number>;
31
46
  }
32
47
  /**
33
48
  * Where the client comes from. A resolver is what lets a queue name its
@@ -41,14 +56,57 @@ export declare class RedisDriver implements QueueDriver {
41
56
  constructor(source: RedisClientSource, options?: {
42
57
  prefix?: string;
43
58
  visibilityTimeoutMs?: number;
59
+ /**
60
+ * Accept the non-atomic pop on a Redis older than 6.2, in
61
+ * production. Off by default: losing an accepted job is a choice a
62
+ * deployment makes, not one a version check makes for it.
63
+ */
64
+ allowNonAtomicPop?: boolean;
65
+ /**
66
+ * How many times a job may be reclaimed from a stalled worker before
67
+ * it is filed as failed instead of pushed round again. Default `1`,
68
+ * upstream's default for the same setting.
69
+ *
70
+ * Unbounded recovery is a job that kills its worker taking the whole
71
+ * queue down with it, forever: the crash never reaches the failure
72
+ * path, so `attempts` never moves and `maxAttempts` never applies.
73
+ */
74
+ maxStalledCount?: number;
75
+ /**
76
+ * How many failed jobs to keep. Default `1000` — the ceiling the
77
+ * memory driver already had. `0` keeps every one of them.
78
+ *
79
+ * Only enforced when the client answers `ltrim`.
80
+ */
81
+ maxFailedJobs?: number;
44
82
  });
45
- push(job: Job): Promise<void>;
46
- pop(): Promise<Job | null>;
47
- complete(job: Job): Promise<void>;
48
- fail(job: Job, error: string): Promise<void>;
49
- retry(job: Job): Promise<void>;
83
+ /**
84
+ * Renew a lease at half its length: two chances to be heard before the
85
+ * deadline, so one slow round-trip does not hand a running job to somebody
86
+ * else. Read by `QueueManager` while a handler runs.
87
+ */
88
+ get renewIntervalMs(): number;
89
+ push(job: JobRecord): Promise<void>;
90
+ pop(queues?: readonly string[]): Promise<JobRecord | null>;
91
+ /**
92
+ * Say the job is still being worked on, and push its deadline back.
93
+ *
94
+ * Answers `false` when there is nothing left to renew — the lease expired
95
+ * and the job was recovered, or it was recovered and re-popped by another
96
+ * worker, whose claim this one must not extend.
97
+ */
98
+ renew(job: JobRecord): Promise<boolean>;
99
+ complete(job: JobRecord): Promise<void>;
100
+ fail(job: JobRecord, error: string): Promise<void>;
101
+ retry(job: JobRecord): Promise<void>;
50
102
  recoverStale(): Promise<number>;
51
- failed(): Promise<Job[]>;
52
- size(): Promise<number>;
103
+ failed(): Promise<JobRecord[]>;
104
+ /**
105
+ * How many jobs are waiting on `queue` — its list plus its delayed set.
106
+ *
107
+ * A delayed job is queued; it is simply not due. Counting only the list
108
+ * reported an empty queue to anything draining one before shutdown.
109
+ */
110
+ size(queue?: string): Promise<number>;
53
111
  }
54
112
  //# sourceMappingURL=RedisDriver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC3B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,KAAK,CAAC,CACL,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,EAAE,EAAE,MAAM,GAAG,OAAO,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACzC;AAcD;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAC1B,WAAW,GACX,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AA6B9C,qBAAa,WAAY,YAAW,WAAW;;gBAsC7C,MAAM,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;KAAE;IA8BtD,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7B,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAuC1B,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IA8D/B,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAexB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CAI7B"}
1
+ {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"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"}