effect-mq 0.1.0 → 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 +167 -22
- package/dist/Job.d.ts +67 -4
- package/dist/Job.d.ts.map +1 -1
- package/dist/Job.js +76 -3
- package/dist/Job.js.map +1 -1
- package/dist/JobStore.d.ts +174 -3
- package/dist/JobStore.d.ts.map +1 -1
- package/dist/JobStore.js +89 -1
- package/dist/JobStore.js.map +1 -1
- package/dist/MemoryJobStore.d.ts +37 -6
- package/dist/MemoryJobStore.d.ts.map +1 -1
- package/dist/MemoryJobStore.js +201 -25
- package/dist/MemoryJobStore.js.map +1 -1
- package/dist/Worker.d.ts +5 -1
- package/dist/Worker.d.ts.map +1 -1
- package/dist/Worker.js +116 -10
- package/dist/Worker.js.map +1 -1
- package/dist/{drizzle → drizzle-postgres}/DrizzleJobStore.d.ts +18 -2
- package/dist/drizzle-postgres/DrizzleJobStore.d.ts.map +1 -0
- package/dist/{drizzle → drizzle-postgres}/DrizzleJobStore.js +287 -40
- package/dist/drizzle-postgres/DrizzleJobStore.js.map +1 -0
- package/dist/drizzle-postgres/index.d.ts.map +1 -0
- package/dist/drizzle-postgres/index.js.map +1 -0
- package/dist/{drizzle → drizzle-postgres}/schema.d.ts +306 -4
- package/dist/drizzle-postgres/schema.d.ts.map +1 -0
- package/dist/{drizzle → drizzle-postgres}/schema.js +36 -2
- package/dist/drizzle-postgres/schema.js.map +1 -0
- package/dist/redis/RedisJobStore.d.ts +56 -0
- package/dist/redis/RedisJobStore.d.ts.map +1 -0
- package/dist/redis/RedisJobStore.js +385 -0
- package/dist/redis/RedisJobStore.js.map +1 -0
- package/dist/redis/index.d.ts +9 -0
- package/dist/redis/index.d.ts.map +1 -0
- package/dist/redis/index.js +9 -0
- package/dist/redis/index.js.map +1 -0
- package/dist/redis/scripts.d.ts +168 -0
- package/dist/redis/scripts.d.ts.map +1 -0
- package/dist/redis/scripts.js +755 -0
- package/dist/redis/scripts.js.map +1 -0
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +332 -3
- package/dist/testing/conformance.js.map +1 -1
- package/package.json +8 -4
- package/src/Job.ts +189 -5
- package/src/JobStore.ts +252 -4
- package/src/MemoryJobStore.ts +273 -26
- package/src/Worker.ts +152 -10
- package/src/{drizzle → drizzle-postgres}/DrizzleJobStore.ts +412 -40
- package/src/{drizzle → drizzle-postgres}/schema.ts +52 -3
- package/src/redis/RedisJobStore.ts +597 -0
- package/src/redis/index.ts +8 -0
- package/src/redis/scripts.ts +862 -0
- package/src/testing/conformance.ts +421 -3
- package/dist/drizzle/DrizzleJobStore.d.ts.map +0 -1
- package/dist/drizzle/DrizzleJobStore.js.map +0 -1
- package/dist/drizzle/index.d.ts.map +0 -1
- package/dist/drizzle/index.js.map +0 -1
- package/dist/drizzle/schema.d.ts.map +0 -1
- package/dist/drizzle/schema.js.map +0 -1
- /package/dist/{drizzle → drizzle-postgres}/index.d.ts +0 -0
- /package/dist/{drizzle → drizzle-postgres}/index.js +0 -0
- /package/src/{drizzle → drizzle-postgres}/index.ts +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Redis-backed `JobStore` built on `effect/unstable/persistence`'s `Redis`
|
|
3
|
+
* service. Every mutation is a single Lua script (see `scripts.ts`), so all
|
|
4
|
+
* `JobStore` operations are atomic on the server and safe across processes.
|
|
5
|
+
*
|
|
6
|
+
* Provide the `Redis` service from your platform package — `NodeRedis.layer`
|
|
7
|
+
* (`@effect/platform-node`, node-redis), `BunRedis.layer`
|
|
8
|
+
* (`@effect/platform-bun`, `Bun.redis`) — or `Redis.make` over any client.
|
|
9
|
+
*
|
|
10
|
+
* Wake-ups ride the client's pub/sub channel, so workers in other processes
|
|
11
|
+
* pick jobs up promptly; the worker's `pollInterval` is the fallback.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.2.0
|
|
14
|
+
*/
|
|
15
|
+
import { Clock, Deferred, Duration, Effect, Exit, Layer, Option, Queue, Schedule } from "effect";
|
|
16
|
+
import { Redis } from "effect/unstable/persistence";
|
|
17
|
+
import * as JobStore from "../JobStore.js";
|
|
18
|
+
import * as scripts from "./scripts.js";
|
|
19
|
+
const storeError = (message) => (cause) => new JobStore.JobStoreError({ message, cause });
|
|
20
|
+
/** Fold a Lua `HGETALL` reply (flat `[field, value, ...]`) into a map. */
|
|
21
|
+
const foldPairs = (flat) => {
|
|
22
|
+
const out = new Map();
|
|
23
|
+
for (let i = 0; i + 1 < flat.length; i += 2) {
|
|
24
|
+
const field = flat[i];
|
|
25
|
+
const value = flat[i + 1];
|
|
26
|
+
if (field !== undefined && value !== undefined) {
|
|
27
|
+
out.set(field, value);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
};
|
|
32
|
+
// Hash fields use "" for absent optional values.
|
|
33
|
+
const optionalString = (value) => value === undefined || value === "" ? undefined : value;
|
|
34
|
+
const optionalNumber = (value) => value === undefined || value === "" ? undefined : Number(value);
|
|
35
|
+
const optionalJson = (value) => {
|
|
36
|
+
if (value === undefined || value === "")
|
|
37
|
+
return undefined;
|
|
38
|
+
// SAFETY: the value round-trips JSON this driver itself wrote for the field.
|
|
39
|
+
return JSON.parse(value);
|
|
40
|
+
};
|
|
41
|
+
const toRecord = (hash) => ({
|
|
42
|
+
id: JobStore.JobId(hash.get("id") ?? ""),
|
|
43
|
+
name: hash.get("name") ?? "",
|
|
44
|
+
queue: JobStore.QueueName(hash.get("queue") ?? ""),
|
|
45
|
+
payload: optionalJson(hash.get("payload")) ?? null,
|
|
46
|
+
metadata: optionalJson(hash.get("metadata")) ?? {},
|
|
47
|
+
// SAFETY: the state field is only ever written with JobState members.
|
|
48
|
+
state: (hash.get("state") ?? "waiting"),
|
|
49
|
+
priority: Number(hash.get("priority") ?? 0),
|
|
50
|
+
attemptsMax: Number(hash.get("attemptsMax") ?? 1),
|
|
51
|
+
attemptsMade: Number(hash.get("attemptsMade") ?? 0),
|
|
52
|
+
stalledCount: Number(hash.get("stalledCount") ?? 0),
|
|
53
|
+
backoff: optionalJson(hash.get("backoff")),
|
|
54
|
+
keep: optionalJson(hash.get("keep")),
|
|
55
|
+
timeoutMs: optionalNumber(hash.get("timeoutMs")),
|
|
56
|
+
cancelRequested: hash.get("cancelRequested") === "1",
|
|
57
|
+
runAt: Number(hash.get("runAt") ?? 0),
|
|
58
|
+
enqueuedAt: Number(hash.get("enqueuedAt") ?? 0),
|
|
59
|
+
processedAt: optionalNumber(hash.get("processedAt")),
|
|
60
|
+
finishedAt: optionalNumber(hash.get("finishedAt")),
|
|
61
|
+
exit: optionalJson(hash.get("exit")),
|
|
62
|
+
failedReason: optionalString(hash.get("failedReason"))
|
|
63
|
+
});
|
|
64
|
+
const toSchedule = (hash) => ({
|
|
65
|
+
key: JobStore.ScheduleKey(hash.get("key") ?? ""),
|
|
66
|
+
jobName: hash.get("jobName") ?? "",
|
|
67
|
+
queue: JobStore.QueueName(hash.get("queue") ?? ""),
|
|
68
|
+
cron: optionalString(hash.get("cron")),
|
|
69
|
+
tz: optionalString(hash.get("tz")),
|
|
70
|
+
everyMs: optionalNumber(hash.get("everyMs")),
|
|
71
|
+
payload: optionalJson(hash.get("payload")),
|
|
72
|
+
metadata: optionalJson(hash.get("metadata")) ?? {},
|
|
73
|
+
priority: Number(hash.get("priority") ?? 0),
|
|
74
|
+
attemptsMax: Number(hash.get("attemptsMax") ?? 1),
|
|
75
|
+
backoff: optionalJson(hash.get("backoff")),
|
|
76
|
+
keep: optionalJson(hash.get("keep")),
|
|
77
|
+
timeoutMs: optionalNumber(hash.get("timeoutMs")),
|
|
78
|
+
nextRunAt: Number(hash.get("nextRunAt") ?? 0)
|
|
79
|
+
});
|
|
80
|
+
// cjson encodes an empty Lua table as {}, not [] — normalize.
|
|
81
|
+
const asArray = (value) => Array.isArray(value) ? value : [];
|
|
82
|
+
const JOB_STATES = [
|
|
83
|
+
"waiting",
|
|
84
|
+
"delayed",
|
|
85
|
+
"active",
|
|
86
|
+
"completed",
|
|
87
|
+
"failed",
|
|
88
|
+
"cancelled"
|
|
89
|
+
];
|
|
90
|
+
/**
|
|
91
|
+
* Build a `RedisJobStore` service. Needs the `Redis` service and a `Scope`
|
|
92
|
+
* (the wake-up subscription and the optional history sweeper live in it).
|
|
93
|
+
*
|
|
94
|
+
* @since 0.2.0
|
|
95
|
+
*/
|
|
96
|
+
export const make = (options) => Effect.gen(function* () {
|
|
97
|
+
const redis = yield* Redis.Redis;
|
|
98
|
+
const prefix = options?.prefix ?? "effect-mq";
|
|
99
|
+
const wakeChannel = `${prefix}:wake`;
|
|
100
|
+
const evalEnqueue = redis.eval(scripts.enqueue);
|
|
101
|
+
const evalClaim = redis.eval(scripts.claim);
|
|
102
|
+
const evalAck = redis.eval(scripts.ack);
|
|
103
|
+
const evalRelease = redis.eval(scripts.release);
|
|
104
|
+
const evalExtendLocks = redis.eval(scripts.extendLocks);
|
|
105
|
+
const evalRecoverStalled = redis.eval(scripts.recoverStalled);
|
|
106
|
+
const evalGetJob = redis.eval(scripts.getJob);
|
|
107
|
+
const evalList = redis.eval(scripts.list);
|
|
108
|
+
const evalCounts = redis.eval(scripts.counts);
|
|
109
|
+
const evalRemove = redis.eval(scripts.remove);
|
|
110
|
+
const evalRetry = redis.eval(scripts.retry);
|
|
111
|
+
const evalCancel = redis.eval(scripts.cancel);
|
|
112
|
+
const evalPromote = redis.eval(scripts.promote);
|
|
113
|
+
const evalUpsertSchedule = redis.eval(scripts.upsertSchedule);
|
|
114
|
+
const evalRemoveSchedule = redis.eval(scripts.removeSchedule);
|
|
115
|
+
const evalListSchedules = redis.eval(scripts.listSchedules);
|
|
116
|
+
const evalDueSchedules = redis.eval(scripts.dueSchedules);
|
|
117
|
+
const evalAdvanceSchedule = redis.eval(scripts.advanceSchedule);
|
|
118
|
+
const evalSweepHistory = redis.eval(scripts.sweepHistory);
|
|
119
|
+
// Wake protocol: a local version + Deferred chain (same-process wake-ups
|
|
120
|
+
// never depend on the pub/sub round trip), with the channel carrying
|
|
121
|
+
// cross-process wake-ups. Same shape as the Postgres driver's NOTIFY.
|
|
122
|
+
let wakeVersion = 0;
|
|
123
|
+
let wake = Deferred.makeUnsafe();
|
|
124
|
+
const signalWakeLocal = () => {
|
|
125
|
+
wakeVersion += 1;
|
|
126
|
+
const current = wake;
|
|
127
|
+
wake = Deferred.makeUnsafe();
|
|
128
|
+
Deferred.doneUnsafe(current, Exit.succeed(void 0));
|
|
129
|
+
};
|
|
130
|
+
const wakeUp = Effect.suspend(() => {
|
|
131
|
+
signalWakeLocal();
|
|
132
|
+
return redis.send("PUBLISH", wakeChannel, "1").pipe(Effect.ignore);
|
|
133
|
+
});
|
|
134
|
+
// Cross-process wake-ups. The pump resubscribes on connection loss (Bun
|
|
135
|
+
// subscribers do not auto-reconnect); the retry delay only ever runs
|
|
136
|
+
// after a real failure, so TestClock runs are unaffected.
|
|
137
|
+
yield* Effect.scoped(Effect.gen(function* () {
|
|
138
|
+
const messages = yield* redis.subscribe(wakeChannel);
|
|
139
|
+
while (true) {
|
|
140
|
+
yield* Queue.take(messages);
|
|
141
|
+
signalWakeLocal();
|
|
142
|
+
}
|
|
143
|
+
})).pipe(Effect.retry(Schedule.spaced("1 second")), Effect.catchCause((cause) => Effect.logWarning("effect-mq: redis wake subscription failed", cause)), Effect.forkScoped);
|
|
144
|
+
if (options?.historyTtl !== undefined) {
|
|
145
|
+
const ttlMs = Duration.toMillis(options.historyTtl);
|
|
146
|
+
const intervalMs = Duration.toMillis(options.historySweepInterval ?? "1 minute");
|
|
147
|
+
yield* Effect.gen(function* () {
|
|
148
|
+
yield* Effect.sleep(intervalMs);
|
|
149
|
+
const now = yield* Clock.currentTimeMillis;
|
|
150
|
+
while ((yield* evalSweepHistory(prefix, now - ttlMs, 500)) !== "0") {
|
|
151
|
+
// bounded batches until the window is clean
|
|
152
|
+
}
|
|
153
|
+
}).pipe(Effect.catchCause((cause) => Effect.logError("effect-mq: redis history sweep failed", cause)), Effect.forever, Effect.forkScoped);
|
|
154
|
+
}
|
|
155
|
+
const generateCandidate = (request, generate) => Effect.suspend(() => {
|
|
156
|
+
const raw = generate(request);
|
|
157
|
+
return Effect.isEffect(raw) ? raw : Effect.succeed(raw);
|
|
158
|
+
});
|
|
159
|
+
const enqueueOnce = (request, idMode, id, now) => evalEnqueue(prefix, idMode, id, request.name, request.queue, JSON.stringify(request.payload ?? null), JSON.stringify(request.metadata), request.priority, request.attemptsMax, request.backoff === undefined ? "" : JSON.stringify(request.backoff), request.keep === undefined ? "" : JSON.stringify(request.keep), request.timeoutMs === undefined ? "" : String(request.timeoutMs), Math.max(0, request.delayMs), now);
|
|
160
|
+
const store = {
|
|
161
|
+
enqueue: (request) => Effect.gen(function* () {
|
|
162
|
+
const now = yield* Clock.currentTimeMillis;
|
|
163
|
+
const generate = options?.idGenerator;
|
|
164
|
+
for (let i = 0; i < 5; i++) {
|
|
165
|
+
const mode = request.id !== undefined
|
|
166
|
+
? "user"
|
|
167
|
+
: generate !== undefined
|
|
168
|
+
? "generated"
|
|
169
|
+
: "auto";
|
|
170
|
+
const candidate = mode === "user"
|
|
171
|
+
? request.id ?? ""
|
|
172
|
+
: mode === "generated" && generate !== undefined
|
|
173
|
+
? yield* generateCandidate(request, generate)
|
|
174
|
+
: "";
|
|
175
|
+
const reply = JSON.parse(yield* enqueueOnce(request, mode, candidate, now));
|
|
176
|
+
if (reply.collision === true)
|
|
177
|
+
continue;
|
|
178
|
+
if (reply.error !== undefined || reply.id === undefined) {
|
|
179
|
+
return yield* new JobStore.JobStoreError({
|
|
180
|
+
message: "enqueue failed: could not generate a unique job id"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (reply.wake === true) {
|
|
184
|
+
yield* wakeUp;
|
|
185
|
+
}
|
|
186
|
+
return { id: JobStore.JobId(reply.id), duplicate: reply.duplicate === true };
|
|
187
|
+
}
|
|
188
|
+
return yield* new JobStore.JobStoreError({
|
|
189
|
+
message: "enqueue failed: could not generate a unique job id"
|
|
190
|
+
});
|
|
191
|
+
}).pipe(Effect.mapError((error) => error instanceof JobStore.JobStoreError ? error : storeError("enqueue failed")(error))),
|
|
192
|
+
claim: (claimOptions) =>
|
|
193
|
+
// Snapshot BEFORE the script runs: a wake that fires while the claim
|
|
194
|
+
// executes must make awaitWake(token) return immediately.
|
|
195
|
+
Effect.suspend(() => {
|
|
196
|
+
const observedWake = wakeVersion;
|
|
197
|
+
return Effect.gen(function* () {
|
|
198
|
+
const now = yield* Clock.currentTimeMillis;
|
|
199
|
+
const reply = JSON.parse(yield* evalClaim(prefix, claimOptions.queue, JSON.stringify(claimOptions.names), claimOptions.token, claimOptions.lockDurationMs, now));
|
|
200
|
+
if (reply.job !== undefined) {
|
|
201
|
+
const claimed = { _tag: "Claimed", job: toRecord(foldPairs(reply.job)) };
|
|
202
|
+
return claimed;
|
|
203
|
+
}
|
|
204
|
+
const empty = {
|
|
205
|
+
_tag: "Empty",
|
|
206
|
+
nextRunAt: reply.nextRunAt,
|
|
207
|
+
wakeToken: observedWake
|
|
208
|
+
};
|
|
209
|
+
return empty;
|
|
210
|
+
});
|
|
211
|
+
}).pipe(Effect.mapError(storeError("claim failed"))),
|
|
212
|
+
ack: (id, token, outcome) => Effect.gen(function* () {
|
|
213
|
+
const now = yield* Clock.currentTimeMillis;
|
|
214
|
+
const exitJson = outcome._tag === "Cancelled" || outcome.exit === undefined
|
|
215
|
+
? ""
|
|
216
|
+
: JSON.stringify(outcome.exit);
|
|
217
|
+
const delayMs = outcome._tag === "Retry" ? Math.max(0, outcome.delayMs) : 0;
|
|
218
|
+
const reply = JSON.parse(yield* evalAck(prefix, id, token, outcome._tag, exitJson, delayMs, now).pipe(Effect.mapError(storeError("ack failed"))));
|
|
219
|
+
if (reply.error === "notfound")
|
|
220
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
221
|
+
if (reply.error === "locklost")
|
|
222
|
+
return yield* new JobStore.LockLostError({ jobId: id });
|
|
223
|
+
if (reply.wake === true) {
|
|
224
|
+
yield* wakeUp;
|
|
225
|
+
}
|
|
226
|
+
}),
|
|
227
|
+
release: (id, token) => Effect.gen(function* () {
|
|
228
|
+
const now = yield* Clock.currentTimeMillis;
|
|
229
|
+
const reply = JSON.parse(yield* evalRelease(prefix, id, token, now).pipe(Effect.mapError(storeError("release failed"))));
|
|
230
|
+
if (reply.error === "notfound")
|
|
231
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
232
|
+
if (reply.error === "locklost")
|
|
233
|
+
return yield* new JobStore.LockLostError({ jobId: id });
|
|
234
|
+
if (reply.wake === true) {
|
|
235
|
+
yield* wakeUp;
|
|
236
|
+
}
|
|
237
|
+
}),
|
|
238
|
+
extendLocks: (locks, durationMs) => Effect.gen(function* () {
|
|
239
|
+
if (locks.length === 0) {
|
|
240
|
+
const empty = { lost: [], cancelRequested: [] };
|
|
241
|
+
return empty;
|
|
242
|
+
}
|
|
243
|
+
const now = yield* Clock.currentTimeMillis;
|
|
244
|
+
const reply = JSON.parse(yield* evalExtendLocks(prefix, JSON.stringify(locks), durationMs, now));
|
|
245
|
+
const result = {
|
|
246
|
+
lost: asArray(reply.lost).map(JobStore.JobId),
|
|
247
|
+
cancelRequested: asArray(reply.cancel).map(JobStore.JobId)
|
|
248
|
+
};
|
|
249
|
+
return result;
|
|
250
|
+
}).pipe(Effect.mapError(storeError("extendLocks failed"))),
|
|
251
|
+
recoverStalled: (recoverOptions) => Effect.gen(function* () {
|
|
252
|
+
const now = yield* Clock.currentTimeMillis;
|
|
253
|
+
const recovered = JSON.parse(yield* evalRecoverStalled(prefix, recoverOptions.maxStalledCount, now));
|
|
254
|
+
const result = recovered.map((entry) => ({ id: JobStore.JobId(entry.id), failed: entry.failed }));
|
|
255
|
+
if (result.some((entry) => !entry.failed)) {
|
|
256
|
+
yield* wakeUp;
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}).pipe(Effect.mapError(storeError("recoverStalled failed"))),
|
|
260
|
+
awaitWake: (_queues, wakeToken) => Effect.suspend(() => {
|
|
261
|
+
if (wakeVersion > wakeToken)
|
|
262
|
+
return Effect.void;
|
|
263
|
+
return Deferred.await(wake);
|
|
264
|
+
}),
|
|
265
|
+
getJob: (id) => evalGetJob(prefix, id).pipe(Effect.mapError(storeError("getJob failed")), Effect.map((raw) => {
|
|
266
|
+
const flat = JSON.parse(raw);
|
|
267
|
+
return flat.length === 0 ? Option.none() : Option.some(toRecord(foldPairs(flat)));
|
|
268
|
+
})),
|
|
269
|
+
getAttempts: (id) => redis.send("LRANGE", `${prefix}:attempts:${id}`, "0", "-1").pipe(Effect.mapError(storeError("getAttempts failed")), Effect.map((raw) => {
|
|
270
|
+
// SAFETY: LRANGE always replies with an array of bulk strings.
|
|
271
|
+
const entries = raw;
|
|
272
|
+
return entries.map((entry) => {
|
|
273
|
+
const parsed = JSON.parse(entry);
|
|
274
|
+
const record = {
|
|
275
|
+
attempt: parsed.attempt,
|
|
276
|
+
startedAt: parsed.startedAt ?? undefined,
|
|
277
|
+
finishedAt: parsed.finishedAt,
|
|
278
|
+
outcome: parsed.outcome,
|
|
279
|
+
// The ledger omits the key entirely for absent exits, so a
|
|
280
|
+
// legitimate encoded null exit survives the round trip.
|
|
281
|
+
exit: Object.hasOwn(parsed, "exit") ? parsed.exit : undefined
|
|
282
|
+
};
|
|
283
|
+
return record;
|
|
284
|
+
});
|
|
285
|
+
})),
|
|
286
|
+
list: (listOptions) => Effect.gen(function* () {
|
|
287
|
+
const limit = Math.max(1, listOptions.limit ?? 50);
|
|
288
|
+
const filters = {
|
|
289
|
+
queue: listOptions.queue,
|
|
290
|
+
name: listOptions.name,
|
|
291
|
+
states: listOptions.states,
|
|
292
|
+
metadata: listOptions.metadata
|
|
293
|
+
};
|
|
294
|
+
const reply = JSON
|
|
295
|
+
.parse(yield* evalList(prefix, JSON.stringify(filters), listOptions.cursor ?? "", limit));
|
|
296
|
+
const items = asArray(reply.items).map((flat) => toRecord(foldPairs(flat)));
|
|
297
|
+
const last = items[items.length - 1];
|
|
298
|
+
const result = {
|
|
299
|
+
items,
|
|
300
|
+
cursor: reply.more && last !== undefined ? `${last.enqueuedAt}:${last.id}` : undefined
|
|
301
|
+
};
|
|
302
|
+
return result;
|
|
303
|
+
}).pipe(Effect.mapError(storeError("list failed"))),
|
|
304
|
+
retry: (id) => Effect.gen(function* () {
|
|
305
|
+
const now = yield* Clock.currentTimeMillis;
|
|
306
|
+
const reply = JSON.parse(yield* evalRetry(prefix, id, now).pipe(Effect.mapError(storeError("retry failed"))));
|
|
307
|
+
if (reply.error === "notfound")
|
|
308
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
309
|
+
if (reply.error === "state") {
|
|
310
|
+
return yield* new JobStore.JobNotRetryableError({ jobId: id, state: reply.state ?? "failed" });
|
|
311
|
+
}
|
|
312
|
+
yield* wakeUp;
|
|
313
|
+
}),
|
|
314
|
+
counts: (queue) => evalCounts(prefix).pipe(Effect.mapError(storeError("counts failed")), Effect.map((raw) => {
|
|
315
|
+
const flat = JSON.parse(raw);
|
|
316
|
+
const byField = foldPairs(flat);
|
|
317
|
+
// SAFETY: fromEntries over the exhaustive JOB_STATES list yields
|
|
318
|
+
// exactly one zeroed entry per JobState member.
|
|
319
|
+
const totals = Object.fromEntries(JOB_STATES.map((state) => [state, 0]));
|
|
320
|
+
for (const [field, count] of byField) {
|
|
321
|
+
const split = field.lastIndexOf("|");
|
|
322
|
+
const fieldQueue = field.slice(0, split);
|
|
323
|
+
// SAFETY: counts fields are written as `<queue>|<JobState>`.
|
|
324
|
+
const state = field.slice(split + 1);
|
|
325
|
+
if (queue === undefined || fieldQueue === queue) {
|
|
326
|
+
totals[state] += Number(count);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return totals;
|
|
330
|
+
})),
|
|
331
|
+
remove: (id) => evalRemove(prefix, id).pipe(Effect.mapError(storeError("remove failed")), Effect.map((raw) => raw !== "0")),
|
|
332
|
+
cancel: (id) => Effect.gen(function* () {
|
|
333
|
+
const now = yield* Clock.currentTimeMillis;
|
|
334
|
+
const reply = JSON.parse(yield* evalCancel(prefix, id, now).pipe(Effect.mapError(storeError("cancel failed"))));
|
|
335
|
+
if (reply.error === "notfound")
|
|
336
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
337
|
+
if (reply.error === "state") {
|
|
338
|
+
return yield* new JobStore.JobNotCancellableError({ jobId: id, state: reply.state ?? "completed" });
|
|
339
|
+
}
|
|
340
|
+
}),
|
|
341
|
+
promote: (id) => Effect.gen(function* () {
|
|
342
|
+
const now = yield* Clock.currentTimeMillis;
|
|
343
|
+
const reply = JSON.parse(yield* evalPromote(prefix, id, now).pipe(Effect.mapError(storeError("promote failed"))));
|
|
344
|
+
if (reply.error === "notfound")
|
|
345
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
346
|
+
if (reply.error === "state") {
|
|
347
|
+
return yield* new JobStore.JobNotPromotableError({ jobId: id, state: reply.state ?? "completed" });
|
|
348
|
+
}
|
|
349
|
+
yield* wakeUp;
|
|
350
|
+
}),
|
|
351
|
+
pause: (queue) => redis.send("SADD", `${prefix}:paused`, queue).pipe(Effect.mapError(storeError("pause failed")), Effect.asVoid),
|
|
352
|
+
resume: (queue) => redis.send("SREM", `${prefix}:paused`, queue).pipe(Effect.mapError(storeError("resume failed")), Effect.flatMap((removed) => Number(removed) > 0 ? wakeUp : Effect.void)),
|
|
353
|
+
pausedQueues: () => redis.send("SMEMBERS", `${prefix}:paused`).pipe(Effect.mapError(storeError("pausedQueues failed")), Effect.map((raw) => {
|
|
354
|
+
// SAFETY: SMEMBERS always replies with an array of bulk strings.
|
|
355
|
+
const members = raw;
|
|
356
|
+
return members.map(JobStore.QueueName);
|
|
357
|
+
})),
|
|
358
|
+
upsertSchedule: (schedule) => evalUpsertSchedule(prefix, schedule.key, schedule.jobName, schedule.queue, schedule.cron ?? "", schedule.tz ?? "", schedule.everyMs === undefined ? "" : String(schedule.everyMs), schedule.payload === undefined ? "" : JSON.stringify(schedule.payload), JSON.stringify(schedule.metadata), String(schedule.priority), String(schedule.attemptsMax), schedule.backoff === undefined ? "" : JSON.stringify(schedule.backoff), schedule.keep === undefined ? "" : JSON.stringify(schedule.keep), schedule.timeoutMs === undefined ? "" : String(schedule.timeoutMs), schedule.nextRunAt).pipe(Effect.mapError(storeError("upsertSchedule failed")), Effect.andThen(wakeUp)),
|
|
359
|
+
removeSchedule: (key) => evalRemoveSchedule(prefix, key).pipe(Effect.mapError(storeError("removeSchedule failed")), Effect.map((raw) => raw !== "0")),
|
|
360
|
+
listSchedules: (listOptions) => evalListSchedules(prefix, JSON.stringify(listOptions ?? {})).pipe(Effect.mapError(storeError("listSchedules failed")), Effect.map((raw) => {
|
|
361
|
+
const flat = JSON.parse(raw);
|
|
362
|
+
return flat.map((pairs) => toSchedule(foldPairs(pairs)));
|
|
363
|
+
})),
|
|
364
|
+
dueSchedules: () => Effect.gen(function* () {
|
|
365
|
+
const now = yield* Clock.currentTimeMillis;
|
|
366
|
+
const flat = JSON.parse(yield* evalDueSchedules(prefix, now));
|
|
367
|
+
return flat.map((pairs) => toSchedule(foldPairs(pairs)));
|
|
368
|
+
}).pipe(Effect.mapError(storeError("dueSchedules failed"))),
|
|
369
|
+
advanceSchedule: (key, expectedRunAt, nextRunAt) => evalAdvanceSchedule(prefix, key, expectedRunAt, nextRunAt).pipe(Effect.mapError(storeError("advanceSchedule failed")), Effect.asVoid)
|
|
370
|
+
};
|
|
371
|
+
return store;
|
|
372
|
+
});
|
|
373
|
+
/**
|
|
374
|
+
* A Redis-backed layer for the default `JobStore`.
|
|
375
|
+
*
|
|
376
|
+
* @since 0.2.0
|
|
377
|
+
*/
|
|
378
|
+
export const layer = (options) => Layer.effect(JobStore.JobStore, make(options));
|
|
379
|
+
/**
|
|
380
|
+
* A Redis-backed layer for a specific named store key.
|
|
381
|
+
*
|
|
382
|
+
* @since 0.2.0
|
|
383
|
+
*/
|
|
384
|
+
export const layerFor = (store, options) => Layer.effect(store, make(options));
|
|
385
|
+
//# sourceMappingURL=RedisJobStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisJobStore.js","sourceRoot":"","sources":["../../src/redis/RedisJobStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Redis-backed `JobStore`, built on `effect/unstable/persistence`'s
|
|
3
|
+
* `Redis` service (provide it via `NodeRedis.layer`, `BunRedis.layer`, or
|
|
4
|
+
* `Redis.make` over any client).
|
|
5
|
+
*
|
|
6
|
+
* @since 0.2.0
|
|
7
|
+
*/
|
|
8
|
+
export * as RedisJobStore from "./RedisJobStore.ts";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redis/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Redis-backed `JobStore`, built on `effect/unstable/persistence`'s
|
|
3
|
+
* `Redis` service (provide it via `NodeRedis.layer`, `BunRedis.layer`, or
|
|
4
|
+
* `Redis.make` over any client).
|
|
5
|
+
*
|
|
6
|
+
* @since 0.2.0
|
|
7
|
+
*/
|
|
8
|
+
export * as RedisJobStore from "./RedisJobStore.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redis/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lua scripts backing `RedisJobStore`.
|
|
3
|
+
*
|
|
4
|
+
* Every mutation is one script, so every `JobStore` method is atomic on the
|
|
5
|
+
* server. Two disciplines apply throughout:
|
|
6
|
+
*
|
|
7
|
+
* - **All time comes in via ARGV** (from the Effect `Clock`) — never Redis
|
|
8
|
+
* `TIME` — so the conformance suite drives this driver under `TestClock`
|
|
9
|
+
* against a real server.
|
|
10
|
+
* - **Numbers that become strings are formatted with `%.0f`** — Lua 5.1's
|
|
11
|
+
* `tostring` renders large integers as `1.7e+12`, which would corrupt ids
|
|
12
|
+
* and stored timestamps.
|
|
13
|
+
*
|
|
14
|
+
* Key layout (all under a configurable prefix, non-cluster):
|
|
15
|
+
*
|
|
16
|
+
* - `p:seq` counter for seq + default job ids
|
|
17
|
+
* - `p:job:<id>` HASH of the job record
|
|
18
|
+
* - `p:attempts:<id>` LIST of JSON attempt-ledger entries
|
|
19
|
+
* - `p:waiting:<queue>` ZSET, score `-priority`, member `<seq %016d>:<id>`
|
|
20
|
+
* (score = priority desc; member lex = FIFO)
|
|
21
|
+
* - `p:delayed:<queue>` ZSET, score `runAt`
|
|
22
|
+
* - `p:active` ZSET, score `lockExpiresAt`
|
|
23
|
+
* - `p:all` ZSET, score `enqueuedAt` (list pagination)
|
|
24
|
+
* - `p:finished` ZSET, score `finishedAt` (history TTL)
|
|
25
|
+
* - `p:terminal:<name>:<state>` ZSET, score `finishedAt` (keep pruning)
|
|
26
|
+
* - `p:counts` HASH `<queue>|<state>` -> integer
|
|
27
|
+
* - `p:paused` SET of paused queues
|
|
28
|
+
* - `p:schedules` / `p:schedule:<key>` ZSET by nextRunAt + HASH per record
|
|
29
|
+
*
|
|
30
|
+
* @since 0.2.0
|
|
31
|
+
*/
|
|
32
|
+
import { Redis } from "effect/unstable/persistence";
|
|
33
|
+
/**
|
|
34
|
+
* enqueue(prefix, idMode, id, name, queue, payloadJson, metadataJson,
|
|
35
|
+
* priority, attemptsMax, backoffJson, keepJson, timeoutMs, delayMs, now)
|
|
36
|
+
* idMode: "user" (dedup no-op), "generated" (collision -> retry sentinel),
|
|
37
|
+
* "auto" (j-<seq>, in-script collision loop).
|
|
38
|
+
*/
|
|
39
|
+
export declare const enqueue: Redis.Script<{
|
|
40
|
+
params: [prefix: string, idMode: string, id: string, name: string, queue: string, payloadJson: string, metadataJson: string, priority: number, attemptsMax: number, backoffJson: string, keepJson: string, timeoutMs: string, delayMs: number, now: number];
|
|
41
|
+
result: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* claim(prefix, queue, namesJson, token, lockDurationMs, now)
|
|
45
|
+
* Promotes due delayed jobs first (also while paused), then claims the best
|
|
46
|
+
* waiting job whose name matches. Returns the claimed record (HGETALL pairs)
|
|
47
|
+
* or an Empty result with the earliest matching delayed runAt.
|
|
48
|
+
*/
|
|
49
|
+
export declare const claim: Redis.Script<{
|
|
50
|
+
params: [prefix: string, queue: string, namesJson: string, token: string, lockDurationMs: number, now: number];
|
|
51
|
+
result: string;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* ack(prefix, id, token, outcomeTag, exitJson, delayMs, now)
|
|
55
|
+
* Token-guarded. Retry on a cancel-requested job finishes it as cancelled
|
|
56
|
+
* (cancellation wins over revival, mirroring release/recoverStalled).
|
|
57
|
+
*/
|
|
58
|
+
export declare const ack: Redis.Script<{
|
|
59
|
+
params: [prefix: string, id: string, token: string, outcomeTag: string, exitJson: string, delayMs: number, now: number];
|
|
60
|
+
result: string;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* release(prefix, id, token, now) — hand the job back without consuming an
|
|
64
|
+
* attempt; a pending cancel wins and finishes the job instead.
|
|
65
|
+
*/
|
|
66
|
+
export declare const release: Redis.Script<{
|
|
67
|
+
params: [prefix: string, id: string, token: string, now: number];
|
|
68
|
+
result: string;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* extendLocks(prefix, locksJson, durationMs, now) -> { lost, cancel }
|
|
72
|
+
* Cancel-requested locks are reported, not extended.
|
|
73
|
+
*/
|
|
74
|
+
export declare const extendLocks: Redis.Script<{
|
|
75
|
+
params: [prefix: string, locksJson: string, durationMs: number, now: number];
|
|
76
|
+
result: string;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* recoverStalled(prefix, maxStalledCount, now) -> recovered [{id, failed}]
|
|
80
|
+
* A pending cancel finishes the job as cancelled (not reported as recovered).
|
|
81
|
+
*/
|
|
82
|
+
export declare const recoverStalled: Redis.Script<{
|
|
83
|
+
params: [prefix: string, maxStalledCount: number, now: number];
|
|
84
|
+
result: string;
|
|
85
|
+
}>;
|
|
86
|
+
/** getJob(prefix, id) -> HGETALL pairs (empty array when missing). */
|
|
87
|
+
export declare const getJob: Redis.Script<{
|
|
88
|
+
params: [prefix: string, id: string];
|
|
89
|
+
result: string;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* list(prefix, filtersJson, cursor, limit)
|
|
93
|
+
* Keyset pagination over p:all, newest first (enqueuedAt DESC, id DESC).
|
|
94
|
+
*/
|
|
95
|
+
export declare const list: Redis.Script<{
|
|
96
|
+
params: [prefix: string, filtersJson: string, cursor: string, limit: number];
|
|
97
|
+
result: string;
|
|
98
|
+
}>;
|
|
99
|
+
/** counts(prefix) -> HGETALL pairs of p:counts. */
|
|
100
|
+
export declare const counts: Redis.Script<{
|
|
101
|
+
params: [prefix: string];
|
|
102
|
+
result: string;
|
|
103
|
+
}>;
|
|
104
|
+
/** remove(prefix, id) -> removed boolean (active jobs are refused). */
|
|
105
|
+
export declare const remove: Redis.Script<{
|
|
106
|
+
params: [prefix: string, id: string];
|
|
107
|
+
result: string;
|
|
108
|
+
}>;
|
|
109
|
+
/** retry(prefix, id, now) — failed -> waiting with a fresh budget. */
|
|
110
|
+
export declare const retry: Redis.Script<{
|
|
111
|
+
params: [prefix: string, id: string, now: number];
|
|
112
|
+
result: string;
|
|
113
|
+
}>;
|
|
114
|
+
/**
|
|
115
|
+
* cancel(prefix, id, now) — waiting/delayed become terminal; active gets the
|
|
116
|
+
* cancel-request flag; terminal states are refused.
|
|
117
|
+
*/
|
|
118
|
+
export declare const cancel: Redis.Script<{
|
|
119
|
+
params: [prefix: string, id: string, now: number];
|
|
120
|
+
result: string;
|
|
121
|
+
}>;
|
|
122
|
+
/** promote(prefix, id, now) — delayed -> waiting now. */
|
|
123
|
+
export declare const promote: Redis.Script<{
|
|
124
|
+
params: [prefix: string, id: string, now: number];
|
|
125
|
+
result: string;
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* upsertSchedule(prefix, key, jobName, queue, cron, tz, everyMs, payloadJson,
|
|
129
|
+
* metadataJson, priority, attemptsMax, backoffJson, keepJson,
|
|
130
|
+
* timeoutMs, nextRunAt)
|
|
131
|
+
* Every field arrives pre-encoded from TS and is stored VERBATIM — routing a
|
|
132
|
+
* record through cjson would corrupt high-precision numbers (14 significant
|
|
133
|
+
* digits) and empty arrays ({}). An unchanged cadence (cron/tz/everyMs)
|
|
134
|
+
* preserves the stored nextRunAt.
|
|
135
|
+
*/
|
|
136
|
+
export declare const upsertSchedule: Redis.Script<{
|
|
137
|
+
params: [prefix: string, key: string, jobName: string, queue: string, cron: string, tz: string, everyMs: string, payloadJson: string, metadataJson: string, priority: string, attemptsMax: string, backoffJson: string, keepJson: string, timeoutMs: string, nextRunAt: number];
|
|
138
|
+
result: string;
|
|
139
|
+
}>;
|
|
140
|
+
/** removeSchedule(prefix, key) -> existed boolean. */
|
|
141
|
+
export declare const removeSchedule: Redis.Script<{
|
|
142
|
+
params: [prefix: string, key: string];
|
|
143
|
+
result: string;
|
|
144
|
+
}>;
|
|
145
|
+
/** listSchedules(prefix, filtersJson) ordered by nextRunAt ascending. */
|
|
146
|
+
export declare const listSchedules: Redis.Script<{
|
|
147
|
+
params: [prefix: string, filtersJson: string];
|
|
148
|
+
result: string;
|
|
149
|
+
}>;
|
|
150
|
+
/** dueSchedules(prefix, now) ordered by nextRunAt ascending. */
|
|
151
|
+
export declare const dueSchedules: Redis.Script<{
|
|
152
|
+
params: [prefix: string, now: number];
|
|
153
|
+
result: string;
|
|
154
|
+
}>;
|
|
155
|
+
/** advanceSchedule(prefix, key, expectedRunAt, nextRunAt) — conditional CAS. */
|
|
156
|
+
export declare const advanceSchedule: Redis.Script<{
|
|
157
|
+
params: [prefix: string, key: string, expectedRunAt: number, nextRunAt: number];
|
|
158
|
+
result: string;
|
|
159
|
+
}>;
|
|
160
|
+
/**
|
|
161
|
+
* sweepHistory(prefix, cutoff, limit) -> number swept (bounded batch; the
|
|
162
|
+
* caller loops until 0).
|
|
163
|
+
*/
|
|
164
|
+
export declare const sweepHistory: Redis.Script<{
|
|
165
|
+
params: [prefix: string, cutoff: number, limit: number];
|
|
166
|
+
result: string;
|
|
167
|
+
}>;
|
|
168
|
+
//# sourceMappingURL=scripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts.d.ts","sourceRoot":"","sources":["../../src/redis/scripts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAA;AAuGnD;;;;;GAKG;AACH,eAAO,MAAM,OAAO;;;EA+EM,CAAA;AAE1B;;;;;GAKG;AACH,eAAO,MAAM,KAAK;;;EAsEQ,CAAA;AAE1B;;;;GAIG;AACH,eAAO,MAAM,GAAG;;;EAwEU,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,OAAO;;;EA4BM,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,WAAW;;;EAuBE,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,cAAc;;;EA+CD,CAAA;AAE1B,sEAAsE;AACtE,eAAO,MAAM,MAAM;;;EAUO,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,IAAI;;;EAsES,CAAA;AAE1B,mDAAmD;AACnD,eAAO,MAAM,MAAM;;;EAUO,CAAA;AAE1B,uEAAuE;AACvE,eAAO,MAAM,MAAM;;;EAcO,CAAA;AAE1B,sEAAsE;AACtE,eAAO,MAAM,KAAK;;;EA2BQ,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,MAAM;;;EAgCO,CAAA;AAE1B,yDAAyD;AACzD,eAAO,MAAM,OAAO;;;EAqBM,CAAA;AAE1B;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc;;;EA4DD,CAAA;AAE1B,sDAAsD;AACtD,eAAO,MAAM,cAAc;;;EAUD,CAAA;AAE1B,yEAAyE;AACzE,eAAO,MAAM,aAAa;;;EAqBA,CAAA;AAE1B,gEAAgE;AAChE,eAAO,MAAM,YAAY;;;EAcC,CAAA;AAE1B,gFAAgF;AAChF,eAAO,MAAM,eAAe;;;EAcF,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,YAAY;;;EAUC,CAAA"}
|