@kitr/jobs 0.0.0-stage → 0.2.1
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/LICENSE +21 -0
- package/README.md +12 -2
- package/dist/commands-Bo7c-TIC.d.ts +89 -0
- package/dist/commands.d.ts +2 -0
- package/dist/commands.js +103 -0
- package/dist/index.d.ts +187 -0
- package/dist/index.js +350 -0
- package/dist/kitr.d.ts +41 -0
- package/dist/kitr.js +73 -0
- package/dist/provider.d.ts +6 -0
- package/dist/provider.js +26 -0
- package/docs/api.md +312 -0
- package/docs/index.md +789 -0
- package/docs/overview.md +81 -0
- package/package.json +70 -3
package/docs/api.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API reference
|
|
3
|
+
description: Every export of @kitr/jobs, with its signature.
|
|
4
|
+
order: 2
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API reference
|
|
8
|
+
|
|
9
|
+
Every export of `@kitr/jobs`, `@kitr/jobs/provider`, read from the published type definitions. The [guide](/packages/jobs/guide) shows them in use.
|
|
10
|
+
|
|
11
|
+
## @kitr/jobs
|
|
12
|
+
|
|
13
|
+
### createJobs
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
function createJobs(app: KitrApp, config?: JobsConfig): Jobs;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Create the jobs service without the provider, for scripts and tests. Takes the same options as `config/jobs.ts`.
|
|
20
|
+
|
|
21
|
+
### createMemoryJobsDriver
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
function createMemoryJobsDriver(options?: MemoryJobsDriverOptions): JobsDriver;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The default driver: an in-process queue sorted by `runAt`. Lost on restart and not shared between
|
|
28
|
+
processes; use `createRedisJobsDriver` for that. A pulled job is reserved, not removed: it
|
|
29
|
+
counts in `size()` until the worker acks it, and returns to the queue if that takes longer than
|
|
30
|
+
`visibilityTimeout`.
|
|
31
|
+
|
|
32
|
+
### createRedisJobsDriver
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
function createRedisJobsDriver(redis: RedisJobsClient, options?: RedisJobsDriverOptions): JobsDriver;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
A durable queue over Redis, shared by every worker. Each due job goes to exactly one worker:
|
|
39
|
+
pulling moves it from the queue to a reserved set, and only the worker whose `ZREM` succeeds
|
|
40
|
+
runs it. A job whose worker dies returns to the queue after `visibilityTimeout`. Scheduled
|
|
41
|
+
jobs queue once per run however many workers poll, through `claim`.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
driver: createRedisJobsDriver(new Redis(process.env.REDIS_URL))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### cronMatches
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
function cronMatches(expression: string, date: Date): boolean;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Does a 5-field cron expression (minute hour day month weekday) match this minute?
|
|
54
|
+
|
|
55
|
+
### defineJob
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
function defineJob<Payload = void>(name: string, options: JobOptions<Payload>): Job<Payload>;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Declare a background job. List it in `config/jobs.ts`, then queue it with `useJobs(app).dispatch(job, payload)`.
|
|
62
|
+
|
|
63
|
+
### parseInterval
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
function parseInterval(text: string): number;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Parse an interval such as `'30s'`, `'5m'` or `'1.5h'` into milliseconds (`'5m'` → 300000). Throws on anything else.
|
|
70
|
+
|
|
71
|
+
### useJobs
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
function useJobs(app: KitrApp): Jobs;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The jobs service the provider bound in this app's container. Throws in the browser, where nothing is bound.
|
|
78
|
+
|
|
79
|
+
### defineConfig
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const defineConfig: <const C extends JobsConfig>(config: C) => C;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Types `config/jobs.ts`. Returns its argument unchanged.
|
|
86
|
+
|
|
87
|
+
### DispatchOptions
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
interface DispatchOptions {
|
|
91
|
+
/** Milliseconds from now. */
|
|
92
|
+
delay?: number;
|
|
93
|
+
/** A fixed time instead. */
|
|
94
|
+
at?: Date;
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The third argument of `dispatch()`: when the job may run.
|
|
99
|
+
|
|
100
|
+
### Job
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
interface Job<Payload = unknown> extends JobOptions<Payload> {
|
|
104
|
+
/** Identifies the job in the queue; keep it stable across deploys. */
|
|
105
|
+
name: string;
|
|
106
|
+
/** The payload type, for inference only. */
|
|
107
|
+
readonly __payload?: Payload;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
A job made by `defineJob`: its options plus the name the queue refers to it by.
|
|
112
|
+
|
|
113
|
+
### JobContext
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
interface JobContext {
|
|
117
|
+
/** The app, for the container and services such as `useMailer(app)`. */
|
|
118
|
+
app: KitrApp;
|
|
119
|
+
/** 1 on the first run, then one more per retry. */
|
|
120
|
+
attempt: number;
|
|
121
|
+
/** The id `dispatch()` returned; the same across retries. */
|
|
122
|
+
jobId: string;
|
|
123
|
+
/** Aborts when the attempt passes its `timeout`; pass it to fetch and database calls. */
|
|
124
|
+
signal: AbortSignal;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The second argument of a job's `run`: the app, the attempt number, the job id and an abort signal.
|
|
129
|
+
|
|
130
|
+
### JobOptions
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
interface JobOptions<Payload> {
|
|
134
|
+
/** Validates the payload when dispatched and when a queue driver hands it back. */
|
|
135
|
+
schema?: StandardSchemaV1<unknown, Payload>;
|
|
136
|
+
/** Retries after a failure. Default 3. */
|
|
137
|
+
retries?: number;
|
|
138
|
+
/** Milliseconds before the first retry, doubled each time. Default 1000. */
|
|
139
|
+
backoff?: number;
|
|
140
|
+
/** Milliseconds a run may take before it is aborted. Default 60 000. */
|
|
141
|
+
timeout?: number;
|
|
142
|
+
/** Run on a schedule: a 5-field cron expression or an `every` interval such as `'5m'`, `'1h'`. */
|
|
143
|
+
schedule?: string | {
|
|
144
|
+
every: string;
|
|
145
|
+
};
|
|
146
|
+
/** The work. Throw to fail the attempt; the return value is what `jobs.run()` resolves with. */
|
|
147
|
+
run(payload: Payload, ctx: JobContext): Promise<unknown> | unknown;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
What `defineJob` takes: the work, plus its schema, retries, backoff, timeout and schedule.
|
|
152
|
+
|
|
153
|
+
### Jobs
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
interface Jobs {
|
|
157
|
+
/** Add jobs after creation, checking their schedules. Returns the service for chaining. */
|
|
158
|
+
register(...jobs: Job<any>[]): Jobs;
|
|
159
|
+
/** Validate the payload and queue the job; resolves with its id. */
|
|
160
|
+
dispatch<P>(job: Job<P>, payload: P, options?: DispatchOptions): Promise<string>;
|
|
161
|
+
/** Run a job now, in this process, with retries; what the worker does. */
|
|
162
|
+
run<P>(job: Job<P>, payload: P, attempt?: number): Promise<unknown>;
|
|
163
|
+
/** Start polling the queue and dispatching scheduled jobs. Idempotent. */
|
|
164
|
+
start(): void;
|
|
165
|
+
/** Stop polling and wait for running jobs to settle. */
|
|
166
|
+
stop(): Promise<void>;
|
|
167
|
+
/** Whether the worker is polling. */
|
|
168
|
+
readonly running: boolean;
|
|
169
|
+
/** The queue driver. */
|
|
170
|
+
readonly driver: JobsDriver;
|
|
171
|
+
/** Known jobs by name. */
|
|
172
|
+
readonly jobs: ReadonlyMap<string, Job<any>>;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The service the provider binds as `jobs`: queue, run and schedule jobs, and control the worker.
|
|
177
|
+
|
|
178
|
+
### JobsConfig
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
interface JobsConfig {
|
|
182
|
+
/** Jobs the worker knows about (`server/jobs/*.ts`). Dispatching by object registers on the fly. */
|
|
183
|
+
jobs?: Job<any>[];
|
|
184
|
+
/** Where queued jobs wait. Default: the in-memory driver, lost on restart. */
|
|
185
|
+
driver?: JobsDriver;
|
|
186
|
+
/** Jobs run at once per process. Default 5. */
|
|
187
|
+
concurrency?: number;
|
|
188
|
+
/** Milliseconds between queue polls. Default 500. */
|
|
189
|
+
pollInterval?: number;
|
|
190
|
+
/** Start the worker when the server starts. Default true; set false for a separate worker process. */
|
|
191
|
+
worker?: boolean;
|
|
192
|
+
/** Called when a job has used up its retries. */
|
|
193
|
+
onFailed?: (job: QueuedJob, error: unknown) => void;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The options in `config/jobs.ts`.
|
|
198
|
+
|
|
199
|
+
### JobsDriver
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
interface JobsDriver {
|
|
203
|
+
/** Identifies the driver, such as `memory` or `redis`. */
|
|
204
|
+
name: string;
|
|
205
|
+
/** Store a job; called by `dispatch()` and for each retry. */
|
|
206
|
+
push(job: QueuedJob): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* Jobs whose `runAt` has passed. A driver that implements `ack` should only reserve them here
|
|
209
|
+
* (hide them from other workers) and delete them in `ack`, so a worker that dies mid-job leaves
|
|
210
|
+
* the job to be picked up again. Without `ack`, pulled jobs are gone from the queue.
|
|
211
|
+
*/
|
|
212
|
+
pull(now: number, limit: number): Promise<QueuedJob[]>;
|
|
213
|
+
/** Called once a pulled job is done with: it ran, it failed for good, or its retry was queued. */
|
|
214
|
+
ack?(job: QueuedJob): Promise<void>;
|
|
215
|
+
/** How many jobs are waiting or running: queued plus reserved (pulled, not yet acked). */
|
|
216
|
+
size(): Promise<number>;
|
|
217
|
+
/** Remove every waiting job. */
|
|
218
|
+
clear(): Promise<void>;
|
|
219
|
+
/**
|
|
220
|
+
* Take a lock named `key` for `ttlMs`, resolving true for the one caller that got it. Workers
|
|
221
|
+
* call it before queuing a scheduled job, so with several workers each cron minute and each
|
|
222
|
+
* `every` interval queues the job once. Without it, every worker queues its own copy: right
|
|
223
|
+
* for one process, a duplicate per extra worker otherwise.
|
|
224
|
+
*/
|
|
225
|
+
claim?(key: string, ttlMs: number): Promise<boolean>;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Where queued work waits. The memory driver is the default; Redis or a table are a few methods.
|
|
230
|
+
|
|
231
|
+
### MemoryJobsDriverOptions
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
interface MemoryJobsDriverOptions {
|
|
235
|
+
/**
|
|
236
|
+
* Milliseconds a pulled job stays reserved. A job the worker never acks (its run is stuck, or
|
|
237
|
+
* the worker loop died and was restarted in this process) goes back to the queue after this.
|
|
238
|
+
* Keep it above your longest job `timeout`, or a slow job runs twice. Default 30 000.
|
|
239
|
+
*/
|
|
240
|
+
visibilityTimeout?: number;
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Options for `createMemoryJobsDriver`.
|
|
245
|
+
|
|
246
|
+
### QueuedJob
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
interface QueuedJob {
|
|
250
|
+
/** The id `dispatch()` returned. */
|
|
251
|
+
id: string;
|
|
252
|
+
/** The job's name. */
|
|
253
|
+
name: string;
|
|
254
|
+
/** The payload as validated at dispatch; must survive JSON for shared drivers. */
|
|
255
|
+
payload: unknown;
|
|
256
|
+
/** 1 for the first run, one more per retry. */
|
|
257
|
+
attempt: number;
|
|
258
|
+
/** ms epoch when it may run. */
|
|
259
|
+
runAt: number;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
A job waiting in the queue, as drivers store it and `onFailed` receives it.
|
|
264
|
+
|
|
265
|
+
### RedisJobsClient
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
interface RedisJobsClient {
|
|
269
|
+
hset(key: string, field: string, value: string): Promise<number>;
|
|
270
|
+
hget(key: string, field: string): Promise<string | null>;
|
|
271
|
+
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
272
|
+
zadd(key: string, score: number, member: string): Promise<number | string>;
|
|
273
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
274
|
+
zrangebyscore(key: string, min: number | string, max: number | string, limit: 'LIMIT', offset: number, count: number): Promise<string[]>;
|
|
275
|
+
zcard(key: string): Promise<number>;
|
|
276
|
+
del(...keys: string[]): Promise<number>;
|
|
277
|
+
set(key: string, value: string, px: 'PX', ms: number, nx: 'NX'): Promise<string | null>;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
The part of an [ioredis](https://github.com/redis/ioredis) client the Redis jobs driver uses.
|
|
282
|
+
An ioredis `Redis` fits as it is.
|
|
283
|
+
|
|
284
|
+
### RedisJobsDriverOptions
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
interface RedisJobsDriverOptions {
|
|
288
|
+
/** Prepended to the driver's keys, so apps sharing a Redis keep separate queues. Default `kitr:jobs:`. */
|
|
289
|
+
prefix?: string;
|
|
290
|
+
/**
|
|
291
|
+
* Milliseconds a pulled job stays hidden from other workers. A worker that dies mid-job leaves
|
|
292
|
+
* it to be picked up again after this. Keep it above your longest job `timeout`, or a slow
|
|
293
|
+
* job runs twice. Default 300 000 (5 minutes).
|
|
294
|
+
*/
|
|
295
|
+
visibilityTimeout?: number;
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Options for `createRedisJobsDriver`.
|
|
300
|
+
|
|
301
|
+
## @kitr/jobs/provider
|
|
302
|
+
|
|
303
|
+
### jobsProvider
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
const jobsProvider: import("@kitr/core").KitrProvider;
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Binds `jobs` from `config/jobs.ts`. The worker starts when the server is ready and drains
|
|
310
|
+
on shutdown; `worker: false` leaves starting to a separate process (`jobs.start()`).
|
|
311
|
+
|
|
312
|
+
<!-- GENERATED by scripts/api-docs.mjs from the type definitions. Do not edit. -->
|