@weifuwujs/tasks 0.9.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 +170 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +319 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres.d.ts +3 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +2 -0
- package/dist/postgres.js.map +1 -0
- package/dist/redis.d.ts +3 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +2 -0
- package/dist/redis.js.map +1 -0
- package/dist/sqlite.d.ts +3 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +2 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/stores/memory.d.ts +6 -0
- package/dist/stores/memory.d.ts.map +1 -0
- package/dist/stores/memory.js +169 -0
- package/dist/stores/memory.js.map +1 -0
- package/dist/stores/postgres.d.ts +22 -0
- package/dist/stores/postgres.d.ts.map +1 -0
- package/dist/stores/postgres.js +233 -0
- package/dist/stores/postgres.js.map +1 -0
- package/dist/stores/redis.d.ts +21 -0
- package/dist/stores/redis.d.ts.map +1 -0
- package/dist/stores/redis.js +340 -0
- package/dist/stores/redis.js.map +1 -0
- package/dist/stores/sqlite.d.ts +13 -0
- package/dist/stores/sqlite.d.ts.map +1 -0
- package/dist/stores/sqlite.js +216 -0
- package/dist/stores/sqlite.js.map +1 -0
- package/dist/tasks.d.ts +11 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +214 -0
- package/dist/tasks.js.map +1 -0
- package/dist/testing.d.ts +13 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +211 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +158 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
const DEFAULT_MAX_ATTEMPTS = 5;
|
|
3
|
+
/**
|
|
4
|
+
* claim 单段 Lua:回收过期锁 → 按 runAt 领取(attempts+1、进 processing),同一 EVAL 内完成。
|
|
5
|
+
*
|
|
6
|
+
* KEYS:data / idem / ready / processing / done
|
|
7
|
+
* ARGV:now(ms) / cutoff(ms) / nowIso / workerId / limit / names(`*`=不过滤,否则 JSON 数组,`[]`=全部拒绝)
|
|
8
|
+
*
|
|
9
|
+
* 时钟由 ARGV 传入(Lua 内不得取 TIME),保证契约可注入确定性时钟。
|
|
10
|
+
*/
|
|
11
|
+
const CLAIM_LUA = `
|
|
12
|
+
local dataKey, idemKey, readyKey, procKey, doneKey = KEYS[1], KEYS[2], KEYS[3], KEYS[4], KEYS[5]
|
|
13
|
+
local now, cutoff = tonumber(ARGV[1]), tonumber(ARGV[2])
|
|
14
|
+
local nowIso, worker, limit = ARGV[3], ARGV[4], tonumber(ARGV[5])
|
|
15
|
+
local filter = ARGV[6]
|
|
16
|
+
|
|
17
|
+
local function allowed(name)
|
|
18
|
+
if filter == '*' then return true end
|
|
19
|
+
local names = cjson.decode(filter)
|
|
20
|
+
if names == nil or names == cjson.null or #names == 0 then return false end
|
|
21
|
+
for _, n in ipairs(names) do
|
|
22
|
+
if n == name then return true end
|
|
23
|
+
end
|
|
24
|
+
return false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local candidates = {}
|
|
28
|
+
local expired = redis.call('ZRANGEBYSCORE', procKey, '-inf', cutoff)
|
|
29
|
+
for _, id in ipairs(expired) do
|
|
30
|
+
local json = redis.call('HGET', dataKey, id)
|
|
31
|
+
if json then
|
|
32
|
+
local task = cjson.decode(json)
|
|
33
|
+
if task.attempts >= task.maxAttempts then
|
|
34
|
+
task.status = 'dead'
|
|
35
|
+
task.lockedBy = cjson.null
|
|
36
|
+
task.lockedAt = cjson.null
|
|
37
|
+
task.lastError = 'visibility timeout exceeded'
|
|
38
|
+
task.updatedAt = nowIso
|
|
39
|
+
task.updatedAtMs = now
|
|
40
|
+
redis.call('HSET', dataKey, id, cjson.encode(task))
|
|
41
|
+
redis.call('ZREM', procKey, id)
|
|
42
|
+
redis.call('ZADD', doneKey, now, id)
|
|
43
|
+
else
|
|
44
|
+
task.status = 'pending'
|
|
45
|
+
task.lockedBy = cjson.null
|
|
46
|
+
task.lockedAt = cjson.null
|
|
47
|
+
task.updatedAt = nowIso
|
|
48
|
+
task.updatedAtMs = now
|
|
49
|
+
redis.call('HSET', dataKey, id, cjson.encode(task))
|
|
50
|
+
redis.call('ZREM', procKey, id)
|
|
51
|
+
redis.call('ZADD', readyKey, tonumber(task.runAtMs), id)
|
|
52
|
+
candidates[#candidates + 1] = id
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
redis.call('ZREM', procKey, id)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
local ready = redis.call('ZRANGEBYSCORE', readyKey, '-inf', now)
|
|
60
|
+
for _, id in ipairs(ready) do
|
|
61
|
+
candidates[#candidates + 1] = id
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
local out = {}
|
|
65
|
+
for _, id in ipairs(candidates) do
|
|
66
|
+
if #out >= limit then break end
|
|
67
|
+
local json = redis.call('HGET', dataKey, id)
|
|
68
|
+
if json then
|
|
69
|
+
local task = cjson.decode(json)
|
|
70
|
+
if task.status == 'pending' and tonumber(task.runAtMs) <= now and allowed(task.name) then
|
|
71
|
+
task.status = 'running'
|
|
72
|
+
task.lockedBy = worker
|
|
73
|
+
task.lockedAt = nowIso
|
|
74
|
+
task.attempts = task.attempts + 1
|
|
75
|
+
task.updatedAt = nowIso
|
|
76
|
+
task.updatedAtMs = now
|
|
77
|
+
redis.call('HSET', dataKey, id, cjson.encode(task))
|
|
78
|
+
redis.call('ZREM', readyKey, id)
|
|
79
|
+
redis.call('ZADD', procKey, now, id)
|
|
80
|
+
out[#out + 1] = cjson.encode(task)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
return out
|
|
85
|
+
`;
|
|
86
|
+
function toStored(task) {
|
|
87
|
+
return {
|
|
88
|
+
...task,
|
|
89
|
+
runAt: task.runAt.toISOString(),
|
|
90
|
+
runAtMs: task.runAt.getTime(),
|
|
91
|
+
lockedAt: task.lockedAt ? task.lockedAt.toISOString() : null,
|
|
92
|
+
createdAt: task.createdAt.toISOString(),
|
|
93
|
+
createdAtMs: task.createdAt.getTime(),
|
|
94
|
+
updatedAt: task.updatedAt.toISOString(),
|
|
95
|
+
updatedAtMs: task.updatedAt.getTime(),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function toTask(stored) {
|
|
99
|
+
return {
|
|
100
|
+
id: stored.id,
|
|
101
|
+
name: stored.name,
|
|
102
|
+
payload: stored.payload,
|
|
103
|
+
runAt: new Date(stored.runAt),
|
|
104
|
+
attempts: stored.attempts,
|
|
105
|
+
maxAttempts: stored.maxAttempts,
|
|
106
|
+
status: stored.status,
|
|
107
|
+
lockedBy: stored.lockedBy ?? null,
|
|
108
|
+
lockedAt: stored.lockedAt ? new Date(stored.lockedAt) : null,
|
|
109
|
+
idempotencyKey: stored.idempotencyKey ?? null,
|
|
110
|
+
lastError: stored.lastError ?? null,
|
|
111
|
+
createdAt: new Date(stored.createdAt),
|
|
112
|
+
updatedAt: new Date(stored.updatedAt),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* redis 驱动(ZSET + Lua,复用 `ctx.redis` 同一客户端)。
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* redisTaskStore('redis://…', { prefix: 'tasks' })
|
|
120
|
+
* redisTaskStore(ctx.redis) // 注入已有客户端(不负责 close)
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export function redisTaskStore(urlOrRedis, options = {}) {
|
|
124
|
+
const injected = typeof urlOrRedis === 'object' && urlOrRedis !== null
|
|
125
|
+
? urlOrRedis
|
|
126
|
+
: null;
|
|
127
|
+
const { prefix = 'tasks', ...redisOptions } = options;
|
|
128
|
+
const keys = {
|
|
129
|
+
data: `${prefix}:data`,
|
|
130
|
+
idem: `${prefix}:idem`,
|
|
131
|
+
ready: `${prefix}:ready`,
|
|
132
|
+
processing: `${prefix}:processing`,
|
|
133
|
+
done: `${prefix}:done`,
|
|
134
|
+
};
|
|
135
|
+
let client = injected ? Promise.resolve(injected) : null;
|
|
136
|
+
const redis = () => {
|
|
137
|
+
client ??= (async () => {
|
|
138
|
+
const { default: RedisClient } = (await import('ioredis'));
|
|
139
|
+
if (typeof urlOrRedis === 'string')
|
|
140
|
+
return new RedisClient(urlOrRedis, redisOptions);
|
|
141
|
+
if (process.env.REDIS_URL)
|
|
142
|
+
return new RedisClient(process.env.REDIS_URL, redisOptions);
|
|
143
|
+
return new RedisClient(redisOptions);
|
|
144
|
+
})();
|
|
145
|
+
return client;
|
|
146
|
+
};
|
|
147
|
+
const read = async (db, id) => {
|
|
148
|
+
const json = await db.hget(keys.data, id);
|
|
149
|
+
return json ? JSON.parse(json) : null;
|
|
150
|
+
};
|
|
151
|
+
const write = async (db, stored) => {
|
|
152
|
+
await db.hset(keys.data, stored.id, JSON.stringify(stored));
|
|
153
|
+
};
|
|
154
|
+
const flagDone = async (db, stored, now) => {
|
|
155
|
+
await db.zrem(keys.processing, stored.id);
|
|
156
|
+
await db.zadd(keys.done, String(now.getTime()), stored.id);
|
|
157
|
+
};
|
|
158
|
+
const store = {
|
|
159
|
+
async migrate() {
|
|
160
|
+
// redis 无 schema:键在首次写入时自动出现
|
|
161
|
+
},
|
|
162
|
+
async close() {
|
|
163
|
+
if (!client || injected)
|
|
164
|
+
return;
|
|
165
|
+
const db = await client;
|
|
166
|
+
client = null;
|
|
167
|
+
await db.quit();
|
|
168
|
+
},
|
|
169
|
+
async enqueue(input) {
|
|
170
|
+
const db = await redis();
|
|
171
|
+
const now = new Date();
|
|
172
|
+
const id = randomUUID();
|
|
173
|
+
const key = input.idempotencyKey;
|
|
174
|
+
if (key) {
|
|
175
|
+
const won = await db.hsetnx(keys.idem, key, id);
|
|
176
|
+
if (won === 0) {
|
|
177
|
+
const existingId = await db.hget(keys.idem, key);
|
|
178
|
+
const existing = existingId ? await read(db, existingId) : null;
|
|
179
|
+
if (existing)
|
|
180
|
+
return { task: toTask(existing), created: false };
|
|
181
|
+
// 幂等键在但数据缺失(写入窗口崩溃):以本次为准恢复
|
|
182
|
+
await db.hset(keys.idem, key, id);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const task = {
|
|
186
|
+
id,
|
|
187
|
+
name: input.name,
|
|
188
|
+
payload: input.payload ?? null,
|
|
189
|
+
runAt: input.runAt ?? now,
|
|
190
|
+
attempts: 0,
|
|
191
|
+
maxAttempts: input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,
|
|
192
|
+
status: 'pending',
|
|
193
|
+
lockedBy: null,
|
|
194
|
+
lockedAt: null,
|
|
195
|
+
idempotencyKey: key ?? null,
|
|
196
|
+
lastError: null,
|
|
197
|
+
createdAt: now,
|
|
198
|
+
updatedAt: now,
|
|
199
|
+
};
|
|
200
|
+
const stored = toStored(task);
|
|
201
|
+
await write(db, stored);
|
|
202
|
+
await db.zadd(keys.ready, String(stored.runAtMs), id);
|
|
203
|
+
return { task, created: true };
|
|
204
|
+
},
|
|
205
|
+
async claim(claimOptions) {
|
|
206
|
+
const db = await redis();
|
|
207
|
+
const now = claimOptions.now;
|
|
208
|
+
const namesArg = claimOptions.names === undefined
|
|
209
|
+
? '*'
|
|
210
|
+
: JSON.stringify(claimOptions.names);
|
|
211
|
+
const raw = (await db.eval(CLAIM_LUA, 5, keys.data, keys.idem, keys.ready, keys.processing, keys.done, String(now.getTime()), String(now.getTime() - claimOptions.visibilityTimeoutMs), now.toISOString(), claimOptions.workerId, String(Math.max(0, claimOptions.limit)), namesArg));
|
|
212
|
+
return raw.map((json) => toTask(JSON.parse(json)));
|
|
213
|
+
},
|
|
214
|
+
async complete(id, now) {
|
|
215
|
+
const db = await redis();
|
|
216
|
+
const stored = await read(db, id);
|
|
217
|
+
if (!stored)
|
|
218
|
+
return;
|
|
219
|
+
stored.status = 'done';
|
|
220
|
+
stored.lockedBy = null;
|
|
221
|
+
stored.lockedAt = null;
|
|
222
|
+
stored.updatedAt = now.toISOString();
|
|
223
|
+
stored.updatedAtMs = now.getTime();
|
|
224
|
+
await write(db, stored);
|
|
225
|
+
await flagDone(db, stored, now);
|
|
226
|
+
},
|
|
227
|
+
async fail(id, input, now) {
|
|
228
|
+
const db = await redis();
|
|
229
|
+
const stored = await read(db, id);
|
|
230
|
+
if (!stored)
|
|
231
|
+
return;
|
|
232
|
+
stored.lockedBy = null;
|
|
233
|
+
stored.lockedAt = null;
|
|
234
|
+
stored.lastError = input.error;
|
|
235
|
+
stored.updatedAt = now.toISOString();
|
|
236
|
+
stored.updatedAtMs = now.getTime();
|
|
237
|
+
if (input.retryAt) {
|
|
238
|
+
stored.status = 'pending';
|
|
239
|
+
stored.runAt = input.retryAt.toISOString();
|
|
240
|
+
stored.runAtMs = input.retryAt.getTime();
|
|
241
|
+
await write(db, stored);
|
|
242
|
+
await db.zrem(keys.processing, id);
|
|
243
|
+
await db.zadd(keys.ready, String(stored.runAtMs), id);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
stored.status = 'dead';
|
|
247
|
+
await write(db, stored);
|
|
248
|
+
await flagDone(db, stored, now);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
async release(id, runAt, now) {
|
|
252
|
+
const db = await redis();
|
|
253
|
+
const stored = await read(db, id);
|
|
254
|
+
if (!stored)
|
|
255
|
+
return;
|
|
256
|
+
stored.status = 'pending';
|
|
257
|
+
stored.runAt = runAt.toISOString();
|
|
258
|
+
stored.runAtMs = runAt.getTime();
|
|
259
|
+
stored.lockedBy = null;
|
|
260
|
+
stored.lockedAt = null;
|
|
261
|
+
stored.updatedAt = now.toISOString();
|
|
262
|
+
stored.updatedAtMs = now.getTime();
|
|
263
|
+
await write(db, stored);
|
|
264
|
+
await db.zrem(keys.processing, id);
|
|
265
|
+
await db.zadd(keys.ready, String(stored.runAtMs), id);
|
|
266
|
+
},
|
|
267
|
+
async retry(id, now) {
|
|
268
|
+
const db = await redis();
|
|
269
|
+
const stored = await read(db, id);
|
|
270
|
+
if (!stored || stored.status !== 'dead')
|
|
271
|
+
return false;
|
|
272
|
+
stored.status = 'pending';
|
|
273
|
+
stored.attempts = 0;
|
|
274
|
+
stored.runAt = now.toISOString();
|
|
275
|
+
stored.runAtMs = now.getTime();
|
|
276
|
+
stored.lockedBy = null;
|
|
277
|
+
stored.lockedAt = null;
|
|
278
|
+
stored.lastError = null;
|
|
279
|
+
stored.updatedAt = now.toISOString();
|
|
280
|
+
stored.updatedAtMs = now.getTime();
|
|
281
|
+
await write(db, stored);
|
|
282
|
+
await db.zrem(keys.done, id);
|
|
283
|
+
await db.zrem(keys.processing, id);
|
|
284
|
+
await db.zadd(keys.ready, String(stored.runAtMs), id);
|
|
285
|
+
return true;
|
|
286
|
+
},
|
|
287
|
+
async get(id) {
|
|
288
|
+
const stored = await read(await redis(), id);
|
|
289
|
+
return stored ? toTask(stored) : null;
|
|
290
|
+
},
|
|
291
|
+
async list(filter = {}) {
|
|
292
|
+
const db = await redis();
|
|
293
|
+
const values = await db.hvals(keys.data);
|
|
294
|
+
let tasks = values.map((json) => toTask(JSON.parse(json)));
|
|
295
|
+
if (filter.statuses && filter.statuses.length > 0) {
|
|
296
|
+
const wanted = new Set(filter.statuses);
|
|
297
|
+
tasks = tasks.filter((task) => wanted.has(task.status));
|
|
298
|
+
}
|
|
299
|
+
if (filter.name)
|
|
300
|
+
tasks = tasks.filter((task) => task.name === filter.name);
|
|
301
|
+
tasks.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
302
|
+
return filter.limit !== undefined ? tasks.slice(0, filter.limit) : tasks;
|
|
303
|
+
},
|
|
304
|
+
async prune(pruneOptions) {
|
|
305
|
+
const db = await redis();
|
|
306
|
+
const statuses = pruneOptions.statuses ?? ['done', 'dead'];
|
|
307
|
+
const threshold = pruneOptions.now.getTime() - pruneOptions.olderThanMs;
|
|
308
|
+
const ids = (await db.zrangebyscore(keys.done, '-inf', String(threshold)));
|
|
309
|
+
let removed = 0;
|
|
310
|
+
for (const id of ids) {
|
|
311
|
+
const stored = await read(db, id);
|
|
312
|
+
if (!stored || !statuses.includes(stored.status))
|
|
313
|
+
continue;
|
|
314
|
+
if (stored.idempotencyKey)
|
|
315
|
+
await db.hdel(keys.idem, stored.idempotencyKey);
|
|
316
|
+
await db.hdel(keys.data, id);
|
|
317
|
+
await db.zrem(keys.done, id);
|
|
318
|
+
await db.zrem(keys.ready, id);
|
|
319
|
+
await db.zrem(keys.processing, id);
|
|
320
|
+
removed += 1;
|
|
321
|
+
}
|
|
322
|
+
return removed;
|
|
323
|
+
},
|
|
324
|
+
async pendingNames(now) {
|
|
325
|
+
const db = await redis();
|
|
326
|
+
const ids = (await db.zrangebyscore(keys.ready, '-inf', String(now.getTime())));
|
|
327
|
+
if (ids.length === 0)
|
|
328
|
+
return [];
|
|
329
|
+
const values = (await db.hmget(keys.data, ...ids));
|
|
330
|
+
const names = new Set();
|
|
331
|
+
for (const json of values) {
|
|
332
|
+
if (json)
|
|
333
|
+
names.add(JSON.parse(json).name);
|
|
334
|
+
}
|
|
335
|
+
return [...names];
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
return store;
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/stores/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import type { TaskStore } from '../types.ts';
|
|
3
|
+
export interface SqliteTaskStore extends TaskStore {
|
|
4
|
+
readonly db: DatabaseSync;
|
|
5
|
+
migrate(): Promise<void>;
|
|
6
|
+
close(): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* sqlite 驱动(`node:sqlite`,零依赖)。构造自动迁移,迁移幂等;
|
|
10
|
+
* `:memory:` 用于测试;**单进程**语义(多进程不承诺,文档写明)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function sqliteTaskStore(path?: string): SqliteTaskStore;
|
|
13
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/stores/sqlite.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAQV,SAAS,EACV,MAAM,aAAa,CAAA;AA8EpB,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAA;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAkB,GAAG,eAAe,CA0MvE"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
5
|
+
const DEFAULT_MAX_ATTEMPTS = 5;
|
|
6
|
+
const SCHEMA = `
|
|
7
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
name TEXT NOT NULL,
|
|
10
|
+
payload TEXT NOT NULL,
|
|
11
|
+
run_at TEXT NOT NULL,
|
|
12
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
13
|
+
max_attempts INTEGER NOT NULL DEFAULT 5,
|
|
14
|
+
status TEXT NOT NULL,
|
|
15
|
+
locked_by TEXT,
|
|
16
|
+
locked_at TEXT,
|
|
17
|
+
idempotency_key TEXT UNIQUE,
|
|
18
|
+
last_error TEXT,
|
|
19
|
+
created_at TEXT NOT NULL,
|
|
20
|
+
updated_at TEXT NOT NULL
|
|
21
|
+
);
|
|
22
|
+
CREATE INDEX IF NOT EXISTS tasks_due_idx ON tasks(status, run_at);
|
|
23
|
+
CREATE INDEX IF NOT EXISTS tasks_name_idx ON tasks(name);
|
|
24
|
+
`;
|
|
25
|
+
function toTask(row) {
|
|
26
|
+
return {
|
|
27
|
+
id: row.id,
|
|
28
|
+
name: row.name,
|
|
29
|
+
payload: JSON.parse(row.payload),
|
|
30
|
+
runAt: new Date(row.run_at),
|
|
31
|
+
attempts: row.attempts,
|
|
32
|
+
maxAttempts: row.max_attempts,
|
|
33
|
+
status: row.status,
|
|
34
|
+
lockedBy: row.locked_by,
|
|
35
|
+
lockedAt: row.locked_at ? new Date(row.locked_at) : null,
|
|
36
|
+
idempotencyKey: row.idempotency_key,
|
|
37
|
+
lastError: row.last_error,
|
|
38
|
+
createdAt: new Date(row.created_at),
|
|
39
|
+
updatedAt: new Date(row.updated_at),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function applyMigrations(db) {
|
|
43
|
+
db.exec('CREATE TABLE IF NOT EXISTS task_migrations (version INTEGER PRIMARY KEY, applied_at TEXT NOT NULL)');
|
|
44
|
+
const applied = db
|
|
45
|
+
.prepare('SELECT version FROM task_migrations WHERE version = ?')
|
|
46
|
+
.get(1);
|
|
47
|
+
if (applied)
|
|
48
|
+
return;
|
|
49
|
+
db.exec('BEGIN');
|
|
50
|
+
try {
|
|
51
|
+
db.exec(SCHEMA);
|
|
52
|
+
db.prepare('INSERT INTO task_migrations (version, applied_at) VALUES (?, ?)').run(1, new Date().toISOString());
|
|
53
|
+
db.exec('COMMIT');
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
db.exec('ROLLBACK');
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* sqlite 驱动(`node:sqlite`,零依赖)。构造自动迁移,迁移幂等;
|
|
62
|
+
* `:memory:` 用于测试;**单进程**语义(多进程不承诺,文档写明)。
|
|
63
|
+
*/
|
|
64
|
+
export function sqliteTaskStore(path = 'data/tasks.db') {
|
|
65
|
+
if (path !== ':memory:')
|
|
66
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
67
|
+
const db = new DatabaseSync(path);
|
|
68
|
+
applyMigrations(db);
|
|
69
|
+
const store = {
|
|
70
|
+
db,
|
|
71
|
+
async migrate() {
|
|
72
|
+
applyMigrations(db);
|
|
73
|
+
},
|
|
74
|
+
close() {
|
|
75
|
+
db.close();
|
|
76
|
+
},
|
|
77
|
+
async enqueue(input) {
|
|
78
|
+
const timestamp = new Date().toISOString();
|
|
79
|
+
const key = input.idempotencyKey ?? null;
|
|
80
|
+
const id = randomUUID();
|
|
81
|
+
try {
|
|
82
|
+
db.prepare(`INSERT INTO tasks (id, name, payload, run_at, attempts, max_attempts, status,
|
|
83
|
+
locked_by, locked_at, idempotency_key, last_error, created_at, updated_at)
|
|
84
|
+
VALUES (?, ?, ?, ?, 0, ?, 'pending', NULL, NULL, ?, NULL, ?, ?)`).run(id, input.name, JSON.stringify(input.payload ?? null), (input.runAt ?? new Date()).toISOString(), input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS, key, timestamp, timestamp);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (key && /UNIQUE/i.test(String(error))) {
|
|
88
|
+
const existing = db
|
|
89
|
+
.prepare('SELECT * FROM tasks WHERE idempotency_key = ?')
|
|
90
|
+
.get(key);
|
|
91
|
+
if (existing)
|
|
92
|
+
return { task: toTask(existing), created: false };
|
|
93
|
+
}
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
const row = db.prepare('SELECT * FROM tasks WHERE id = ?').get(id);
|
|
97
|
+
return { task: toTask(row), created: true };
|
|
98
|
+
},
|
|
99
|
+
async claim(options) {
|
|
100
|
+
const nowIso = options.now.toISOString();
|
|
101
|
+
const cutoff = new Date(options.now.getTime() - options.visibilityTimeoutMs).toISOString();
|
|
102
|
+
db.exec('BEGIN IMMEDIATE');
|
|
103
|
+
try {
|
|
104
|
+
// 1) 锁过期回收:达上限置 dead;否则回 pending 重领
|
|
105
|
+
const expired = db
|
|
106
|
+
.prepare("SELECT * FROM tasks WHERE status = 'running' AND locked_at <= ?")
|
|
107
|
+
.all(cutoff);
|
|
108
|
+
for (const row of expired) {
|
|
109
|
+
if (row.attempts >= row.max_attempts) {
|
|
110
|
+
db.prepare(`UPDATE tasks SET status = 'dead', last_error = 'visibility timeout exceeded',
|
|
111
|
+
locked_by = NULL, locked_at = NULL, updated_at = ? WHERE id = ?`).run(nowIso, row.id);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
db.prepare(`UPDATE tasks SET status = 'pending', locked_by = NULL, locked_at = NULL,
|
|
115
|
+
updated_at = ? WHERE id = ?`).run(nowIso, row.id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// 2) 取到期任务(可选按 handler 名过滤)
|
|
119
|
+
const names = options.names;
|
|
120
|
+
const nameClause = names && names.length > 0
|
|
121
|
+
? `AND name IN (${names.map(() => '?').join(', ')})`
|
|
122
|
+
: names && names.length === 0
|
|
123
|
+
? 'AND 0'
|
|
124
|
+
: '';
|
|
125
|
+
const due = db
|
|
126
|
+
.prepare(`SELECT id FROM tasks WHERE status = 'pending' AND run_at <= ? ${nameClause}
|
|
127
|
+
ORDER BY run_at LIMIT ?`)
|
|
128
|
+
.all(nowIso, ...(names ?? []), Math.max(0, options.limit));
|
|
129
|
+
const claimed = [];
|
|
130
|
+
for (const { id } of due) {
|
|
131
|
+
const result = db
|
|
132
|
+
.prepare(`UPDATE tasks SET status = 'running', locked_by = ?, locked_at = ?,
|
|
133
|
+
attempts = attempts + 1, updated_at = ? WHERE id = ? AND status = 'pending'`)
|
|
134
|
+
.run(options.workerId, nowIso, nowIso, id);
|
|
135
|
+
if (Number(result.changes) !== 1)
|
|
136
|
+
continue;
|
|
137
|
+
const row = db.prepare('SELECT * FROM tasks WHERE id = ?').get(id);
|
|
138
|
+
claimed.push(toTask(row));
|
|
139
|
+
}
|
|
140
|
+
db.exec('COMMIT');
|
|
141
|
+
return claimed;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
db.exec('ROLLBACK');
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
async complete(id, now) {
|
|
149
|
+
db.prepare(`UPDATE tasks SET status = 'done', locked_by = NULL, locked_at = NULL,
|
|
150
|
+
updated_at = ? WHERE id = ?`).run(now.toISOString(), id);
|
|
151
|
+
},
|
|
152
|
+
async fail(id, input, now) {
|
|
153
|
+
if (input.retryAt) {
|
|
154
|
+
db.prepare(`UPDATE tasks SET status = 'pending', run_at = ?, last_error = ?,
|
|
155
|
+
locked_by = NULL, locked_at = NULL, updated_at = ? WHERE id = ?`).run(input.retryAt.toISOString(), input.error, now.toISOString(), id);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
db.prepare(`UPDATE tasks SET status = 'dead', last_error = ?,
|
|
159
|
+
locked_by = NULL, locked_at = NULL, updated_at = ? WHERE id = ?`).run(input.error, now.toISOString(), id);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
async release(id, runAt, now) {
|
|
163
|
+
db.prepare(`UPDATE tasks SET status = 'pending', run_at = ?, locked_by = NULL,
|
|
164
|
+
locked_at = NULL, updated_at = ? WHERE id = ?`).run(runAt.toISOString(), now.toISOString(), id);
|
|
165
|
+
},
|
|
166
|
+
async retry(id, now) {
|
|
167
|
+
const result = db
|
|
168
|
+
.prepare(`UPDATE tasks SET status = 'pending', run_at = ?, attempts = 0,
|
|
169
|
+
locked_by = NULL, locked_at = NULL, updated_at = ?
|
|
170
|
+
WHERE id = ? AND status = 'dead'`)
|
|
171
|
+
.run(now.toISOString(), now.toISOString(), id);
|
|
172
|
+
return Number(result.changes) === 1;
|
|
173
|
+
},
|
|
174
|
+
async get(id) {
|
|
175
|
+
const row = db.prepare('SELECT * FROM tasks WHERE id = ?').get(id);
|
|
176
|
+
return row ? toTask(row) : null;
|
|
177
|
+
},
|
|
178
|
+
async list(filter = {}) {
|
|
179
|
+
const clauses = [];
|
|
180
|
+
const params = [];
|
|
181
|
+
if (filter.statuses && filter.statuses.length > 0) {
|
|
182
|
+
clauses.push(`status IN (${filter.statuses.map(() => '?').join(', ')})`);
|
|
183
|
+
params.push(...filter.statuses);
|
|
184
|
+
}
|
|
185
|
+
if (filter.name) {
|
|
186
|
+
clauses.push('name = ?');
|
|
187
|
+
params.push(filter.name);
|
|
188
|
+
}
|
|
189
|
+
const where = clauses.length > 0 ? `WHERE ${clauses.join(' AND ')}` : '';
|
|
190
|
+
const limit = filter.limit !== undefined ? 'LIMIT ?' : '';
|
|
191
|
+
if (filter.limit !== undefined)
|
|
192
|
+
params.push(filter.limit);
|
|
193
|
+
const rows = db
|
|
194
|
+
.prepare(`SELECT * FROM tasks ${where} ORDER BY created_at ${limit}`)
|
|
195
|
+
.all(...params);
|
|
196
|
+
return rows.map(toTask);
|
|
197
|
+
},
|
|
198
|
+
async prune(options) {
|
|
199
|
+
const statuses = options.statuses ?? ['done', 'dead'];
|
|
200
|
+
const threshold = new Date(options.now.getTime() - options.olderThanMs).toISOString();
|
|
201
|
+
const result = db
|
|
202
|
+
.prepare(`DELETE FROM tasks WHERE status IN (${statuses.map(() => '?').join(', ')})
|
|
203
|
+
AND updated_at <= ?`)
|
|
204
|
+
.run(...statuses, threshold);
|
|
205
|
+
return Number(result.changes);
|
|
206
|
+
},
|
|
207
|
+
async pendingNames(now) {
|
|
208
|
+
const rows = db
|
|
209
|
+
.prepare("SELECT DISTINCT name FROM tasks WHERE status = 'pending' AND run_at <= ?")
|
|
210
|
+
.all(now.toISOString());
|
|
211
|
+
return rows.map((row) => row.name);
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
return store;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/stores/sqlite.ts"],"names":[],"mappings":"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"}
|
package/dist/tasks.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CreateTasksOptions, Tasks } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* 任务队列:handler 注册在进程内,库里只存 `name + payload`。
|
|
4
|
+
*
|
|
5
|
+
* - 至少一次:claim → 执行 → complete;崩溃后锁过期自动回队重跑;
|
|
6
|
+
* - 未知 handler:不领取(保持 pending)并告警一次;改名遗留用 CLI `tasks prune`;
|
|
7
|
+
* - 周期任务 `every`:首次立即到期,完成后排下一次(宕机后 catch-up);
|
|
8
|
+
* - 注入时钟 + runOnce/drain:测试不 sleep。
|
|
9
|
+
*/
|
|
10
|
+
export declare function createTasks(options: CreateTasksOptions): Tasks;
|
|
11
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAQlB,KAAK,EACN,MAAM,YAAY,CAAA;AAEnB;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,KAAK,CA+N9D"}
|