@mhbdev/redis 0.2.1 → 0.2.3
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/CHANGELOG.md +12 -0
- package/dist/bullmq/adapter.d.ts +2 -0
- package/dist/bullmq/adapter.d.ts.map +1 -1
- package/dist/bullmq/adapter.js +13 -3
- package/dist/bullmq/adapter.js.map +1 -1
- package/dist/cache/cache.d.ts.map +1 -1
- package/dist/cache/cache.js +12 -2
- package/dist/cache/cache.js.map +1 -1
- package/dist/core/codec.d.ts.map +1 -1
- package/dist/core/codec.js +5 -1
- package/dist/core/codec.js.map +1 -1
- package/dist/core/executor.d.ts +1 -1
- package/dist/core/executor.d.ts.map +1 -1
- package/dist/core/executor.js +22 -3
- package/dist/core/executor.js.map +1 -1
- package/dist/core/hooks.d.ts +5 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +23 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/ioredis/executor.d.ts +2 -2
- package/dist/ioredis/executor.d.ts.map +1 -1
- package/dist/ioredis/executor.js +6 -6
- package/dist/ioredis/executor.js.map +1 -1
- package/dist/ioredis/pubsub.d.ts +1 -0
- package/dist/ioredis/pubsub.d.ts.map +1 -1
- package/dist/ioredis/pubsub.js +40 -12
- package/dist/ioredis/pubsub.js.map +1 -1
- package/dist/locks/locks.d.ts.map +1 -1
- package/dist/locks/locks.js +14 -4
- package/dist/locks/locks.js.map +1 -1
- package/dist/node/client.d.ts.map +1 -1
- package/dist/node/client.js +28 -20
- package/dist/node/client.js.map +1 -1
- package/dist/node/pool.d.ts +8 -2
- package/dist/node/pool.d.ts.map +1 -1
- package/dist/node/pool.js +53 -27
- package/dist/node/pool.js.map +1 -1
- package/dist/node/pubsub.d.ts.map +1 -1
- package/dist/node/pubsub.js +37 -5
- package/dist/node/pubsub.js.map +1 -1
- package/dist/pubsub/pubsub.d.ts.map +1 -1
- package/dist/pubsub/pubsub.js +9 -1
- package/dist/pubsub/pubsub.js.map +1 -1
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.d.ts.map +1 -1
- package/dist/queue/index.js.map +1 -1
- package/dist/queue/queue.d.ts +20 -0
- package/dist/queue/queue.d.ts.map +1 -1
- package/dist/queue/queue.js +216 -73
- package/dist/queue/queue.js.map +1 -1
- package/dist/rate-limit/contracts.d.ts +1 -0
- package/dist/rate-limit/contracts.d.ts.map +1 -1
- package/dist/rate-limit/contracts.js +59 -26
- package/dist/rate-limit/contracts.js.map +1 -1
- package/docs/adapters.md +3 -1
- package/docs/queues.md +16 -0
- package/package.json +1 -1
package/dist/queue/queue.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsonCodec } from "../core/codec.js";
|
|
2
|
-
import { RedisQueueError } from "../core/errors.js";
|
|
2
|
+
import { asError, RedisQueueError } from "../core/errors.js";
|
|
3
|
+
import { notifyError } from "../core/hooks.js";
|
|
3
4
|
export class RedisQueue {
|
|
4
5
|
options;
|
|
5
6
|
prefix;
|
|
@@ -8,24 +9,35 @@ export class RedisQueue {
|
|
|
8
9
|
visibilityTimeoutMs;
|
|
9
10
|
constructor(options) {
|
|
10
11
|
this.options = options;
|
|
11
|
-
if (!options.name.trim())
|
|
12
|
-
throw new RedisQueueError("Queue name is
|
|
12
|
+
if (!options.name.trim() || options.name.includes("\n"))
|
|
13
|
+
throw new RedisQueueError("Queue name is invalid");
|
|
13
14
|
this.prefix = options.prefix ?? "mhbdev:queue";
|
|
14
15
|
this.valueCodec = options.codec ?? jsonCodec();
|
|
15
16
|
this.maxAttempts = options.maxAttempts ?? 3;
|
|
16
17
|
this.visibilityTimeoutMs = options.visibilityTimeoutMs ?? 30_000;
|
|
18
|
+
if (!this.prefix.trim() || this.prefix.includes("\n"))
|
|
19
|
+
throw new RedisQueueError("Queue prefix is invalid");
|
|
17
20
|
if (!Number.isSafeInteger(this.maxAttempts) || this.maxAttempts <= 0)
|
|
18
21
|
throw new RedisQueueError("Queue max attempts must be positive");
|
|
22
|
+
if (!Number.isSafeInteger(this.visibilityTimeoutMs) || this.visibilityTimeoutMs <= 0)
|
|
23
|
+
throw new RedisQueueError("Queue visibility timeout must be positive");
|
|
19
24
|
}
|
|
20
25
|
async enqueue(data, enqueueOptions = {}) {
|
|
26
|
+
const delayMs = enqueueOptions.delayMs ?? 0;
|
|
27
|
+
if (!Number.isSafeInteger(delayMs) || delayMs < 0)
|
|
28
|
+
throw new RedisQueueError("Queue delay must be a non-negative integer");
|
|
29
|
+
if (!Number.isSafeInteger(Date.now() + delayMs))
|
|
30
|
+
throw new RedisQueueError("Queue delivery time is outside the supported range");
|
|
31
|
+
if (enqueueOptions.jobId !== undefined && !enqueueOptions.jobId.trim())
|
|
32
|
+
throw new RedisQueueError("Queue job ID is required when provided");
|
|
21
33
|
const id = enqueueOptions.jobId ?? crypto.randomUUID();
|
|
22
34
|
const job = { id, data, attempts: 0, enqueuedAt: Date.now() };
|
|
23
35
|
const encoded = this.encode(job);
|
|
24
|
-
if (
|
|
36
|
+
if (delayMs > 0) {
|
|
25
37
|
await this.options.redis.execute([
|
|
26
38
|
"ZADD",
|
|
27
39
|
this.delayedKey,
|
|
28
|
-
String(Date.now() +
|
|
40
|
+
String(Date.now() + delayMs),
|
|
29
41
|
encoded,
|
|
30
42
|
]);
|
|
31
43
|
}
|
|
@@ -69,6 +81,14 @@ export class RedisQueue {
|
|
|
69
81
|
decode(value) {
|
|
70
82
|
try {
|
|
71
83
|
const parsed = JSON.parse(value);
|
|
84
|
+
if (typeof parsed.id !== "string" ||
|
|
85
|
+
!parsed.id.trim() ||
|
|
86
|
+
typeof parsed.data !== "string" ||
|
|
87
|
+
!Number.isSafeInteger(parsed.attempts) ||
|
|
88
|
+
parsed.attempts < 0 ||
|
|
89
|
+
!Number.isSafeInteger(parsed.enqueuedAt) ||
|
|
90
|
+
parsed.enqueuedAt < 0)
|
|
91
|
+
throw new TypeError("Queue job payload has an invalid shape");
|
|
72
92
|
return {
|
|
73
93
|
id: parsed.id,
|
|
74
94
|
data: this.valueCodec.decode(parsed.data),
|
|
@@ -88,6 +108,7 @@ export class RedisQueueWorker {
|
|
|
88
108
|
consumer;
|
|
89
109
|
blockMs;
|
|
90
110
|
concurrency;
|
|
111
|
+
hooks;
|
|
91
112
|
stopping = false;
|
|
92
113
|
running = null;
|
|
93
114
|
constructor(queue, handler, options) {
|
|
@@ -97,6 +118,11 @@ export class RedisQueueWorker {
|
|
|
97
118
|
this.consumer = options.consumer ?? crypto.randomUUID();
|
|
98
119
|
this.blockMs = options.blockMs ?? 1_000;
|
|
99
120
|
this.concurrency = options.concurrency ?? 1;
|
|
121
|
+
this.hooks = options.hooks;
|
|
122
|
+
if (!this.group.trim() || !this.consumer.trim())
|
|
123
|
+
throw new RedisQueueError("Queue consumer group and consumer are required");
|
|
124
|
+
if (!Number.isSafeInteger(this.blockMs) || this.blockMs <= 0)
|
|
125
|
+
throw new RedisQueueError("Queue block time must be a positive integer");
|
|
100
126
|
if (!Number.isSafeInteger(this.concurrency) || this.concurrency <= 0)
|
|
101
127
|
throw new RedisQueueError("Queue concurrency must be positive");
|
|
102
128
|
}
|
|
@@ -104,7 +130,12 @@ export class RedisQueueWorker {
|
|
|
104
130
|
if (this.running)
|
|
105
131
|
return this.running;
|
|
106
132
|
this.stopping = false;
|
|
107
|
-
this.running = this.run()
|
|
133
|
+
this.running = this.run()
|
|
134
|
+
.catch((error) => {
|
|
135
|
+
this.reportError(error);
|
|
136
|
+
throw error;
|
|
137
|
+
})
|
|
138
|
+
.finally(() => {
|
|
108
139
|
this.running = null;
|
|
109
140
|
});
|
|
110
141
|
return this.running;
|
|
@@ -146,25 +177,10 @@ export class RedisQueueWorker {
|
|
|
146
177
|
});
|
|
147
178
|
}
|
|
148
179
|
async promoteDue() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
String(Date.now()),
|
|
154
|
-
"LIMIT",
|
|
155
|
-
"0",
|
|
156
|
-
"100",
|
|
157
|
-
]);
|
|
158
|
-
for (const encoded of due ?? []) {
|
|
159
|
-
await this.queue.redis.execute(["ZREM", this.queue.delayedKey, encoded]);
|
|
160
|
-
await this.queue.redis.execute([
|
|
161
|
-
"XADD",
|
|
162
|
-
this.queue.streamKey,
|
|
163
|
-
"*",
|
|
164
|
-
"payload",
|
|
165
|
-
encoded,
|
|
166
|
-
]);
|
|
167
|
-
}
|
|
180
|
+
await this.queue.redis.eval(PROMOTE_DUE_SCRIPT, {
|
|
181
|
+
keys: [this.queue.delayedKey, this.queue.streamKey],
|
|
182
|
+
arguments: [String(Date.now()), "100"],
|
|
183
|
+
});
|
|
168
184
|
}
|
|
169
185
|
async recoverPending() {
|
|
170
186
|
const response = await this.queue.redis.execute([
|
|
@@ -180,42 +196,75 @@ export class RedisQueueWorker {
|
|
|
180
196
|
return parseAutoClaimResponse(response);
|
|
181
197
|
}
|
|
182
198
|
async process(entry) {
|
|
183
|
-
|
|
199
|
+
let job;
|
|
200
|
+
try {
|
|
201
|
+
job = this.queue.decode(entry.payload);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
this.reportError(error);
|
|
205
|
+
await this.queue.redis.eval(REQUEUE_FAILED_SCRIPT, {
|
|
206
|
+
keys: [this.queue.streamKey, this.queue.deadLetterKey],
|
|
207
|
+
arguments: [this.group, entry.id, entry.payload],
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const context = toJobContext(job);
|
|
212
|
+
this.notifyJobStart(context);
|
|
184
213
|
try {
|
|
185
214
|
await this.handler(job);
|
|
186
|
-
await this.queue.redis.execute([
|
|
187
|
-
"XACK",
|
|
188
|
-
this.queue.streamKey,
|
|
189
|
-
this.group,
|
|
190
|
-
entry.id,
|
|
191
|
-
]);
|
|
192
215
|
}
|
|
193
|
-
catch (
|
|
194
|
-
|
|
195
|
-
"XACK",
|
|
196
|
-
this.queue.streamKey,
|
|
197
|
-
this.group,
|
|
198
|
-
entry.id,
|
|
199
|
-
]);
|
|
200
|
-
if (job.attempts + 1 >= this.queue.attempts) {
|
|
201
|
-
await this.queue.redis.execute([
|
|
202
|
-
"XADD",
|
|
203
|
-
this.queue.deadLetterKey,
|
|
204
|
-
"*",
|
|
205
|
-
"payload",
|
|
206
|
-
this.encodeRetry(job),
|
|
207
|
-
]);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
this.notifyJobFailure(context, error);
|
|
210
218
|
const retry = { ...job, attempts: job.attempts + 1 };
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.queue.streamKey
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
this.encodeRetry(retry),
|
|
217
|
-
|
|
219
|
+
const target = retry.attempts >= this.queue.attempts
|
|
220
|
+
? this.queue.deadLetterKey
|
|
221
|
+
: this.queue.streamKey;
|
|
222
|
+
await this.queue.redis.eval(REQUEUE_FAILED_SCRIPT, {
|
|
223
|
+
keys: [this.queue.streamKey, target],
|
|
224
|
+
arguments: [this.group, entry.id, this.encodeRetry(retry)],
|
|
225
|
+
});
|
|
226
|
+
if (target === this.queue.deadLetterKey)
|
|
227
|
+
this.notifyDeadLetter(toJobContext(retry), error);
|
|
228
|
+
return;
|
|
218
229
|
}
|
|
230
|
+
await this.queue.redis.execute(["XACK", this.queue.streamKey, this.group, entry.id]);
|
|
231
|
+
this.notifyJobComplete(context);
|
|
232
|
+
}
|
|
233
|
+
notifyJobStart(job) {
|
|
234
|
+
try {
|
|
235
|
+
this.hooks?.onJobStart?.(job);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
this.reportError(error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
notifyJobComplete(job) {
|
|
242
|
+
try {
|
|
243
|
+
this.hooks?.onJobComplete?.(job);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
this.reportError(error);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
notifyJobFailure(job, error) {
|
|
250
|
+
const failure = asError(error);
|
|
251
|
+
try {
|
|
252
|
+
this.hooks?.onJobFailure?.(job, failure);
|
|
253
|
+
}
|
|
254
|
+
catch (hookError) {
|
|
255
|
+
this.reportError(hookError);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
notifyDeadLetter(job, error) {
|
|
259
|
+
try {
|
|
260
|
+
this.hooks?.onDeadLetter?.(job, error === undefined ? undefined : asError(error));
|
|
261
|
+
}
|
|
262
|
+
catch (hookError) {
|
|
263
|
+
this.reportError(hookError);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
reportError(error) {
|
|
267
|
+
notifyError(this.hooks?.onError, error);
|
|
219
268
|
}
|
|
220
269
|
encodeRetry(job) {
|
|
221
270
|
return JSON.stringify({
|
|
@@ -227,30 +276,124 @@ export class RedisQueueWorker {
|
|
|
227
276
|
}
|
|
228
277
|
}
|
|
229
278
|
const ENSURE_GROUP_SCRIPT = `local groups = redis.pcall("XINFO", "GROUPS", KEYS[1]) if type(groups) == "table" then for _, group in ipairs(groups) do if group[2] == ARGV[1] then return 0 end end end local result = redis.pcall("XGROUP", "CREATE", KEYS[1], ARGV[1], "0-0", "MKSTREAM") if type(result) == "table" then return 1 end local groupsAfter = redis.pcall("XINFO", "GROUPS", KEYS[1]) if type(groupsAfter) == "table" then for _, group in ipairs(groupsAfter) do if group[2] == ARGV[1] then return 0 end end end return redis.error_reply("Redis consumer group creation failed")`;
|
|
279
|
+
const PROMOTE_DUE_SCRIPT = `local due = redis.call("ZRANGEBYSCORE", KEYS[1], "-inf", ARGV[1], "LIMIT", 0, ARGV[2]) for _, payload in ipairs(due) do redis.call("XADD", KEYS[2], "*", "payload", payload) redis.call("ZREM", KEYS[1], payload) end return #due`;
|
|
280
|
+
const REQUEUE_FAILED_SCRIPT = `redis.call("XADD", KEYS[2], "*", "payload", ARGV[3]) redis.call("XACK", KEYS[1], ARGV[1], ARGV[2]) return 1`;
|
|
230
281
|
function parseStreamResponse(value) {
|
|
231
|
-
if (!Array.isArray(value) || value.length === 0)
|
|
232
|
-
return [];
|
|
233
|
-
const streams = value[0];
|
|
234
|
-
if (!Array.isArray(streams) || !Array.isArray(streams[1]))
|
|
235
|
-
return [];
|
|
236
282
|
const result = [];
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
!Array.isArray(rawEntry[1]))
|
|
283
|
+
const streams = toPairs(value);
|
|
284
|
+
for (const [streamName, rawEntries] of streams) {
|
|
285
|
+
if (keyString(streamName) === undefined)
|
|
241
286
|
continue;
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
287
|
+
for (const rawEntry of toEntries(rawEntries)) {
|
|
288
|
+
const [id, rawFields] = toEntry(rawEntry);
|
|
289
|
+
if (!id)
|
|
290
|
+
continue;
|
|
291
|
+
const payload = getField(rawFields, "payload");
|
|
292
|
+
if (typeof payload === "string")
|
|
293
|
+
result.push({ id, payload });
|
|
294
|
+
}
|
|
247
295
|
}
|
|
248
296
|
return result;
|
|
249
297
|
}
|
|
250
298
|
function parseAutoClaimResponse(value) {
|
|
251
|
-
if (
|
|
252
|
-
return [];
|
|
253
|
-
|
|
299
|
+
if (Array.isArray(value) && Array.isArray(value[1]))
|
|
300
|
+
return parseStreamResponse([["recovered", value[1]]]);
|
|
301
|
+
if (isRecord(value) && Array.isArray(value.messages))
|
|
302
|
+
return parseStreamResponse([["recovered", value.messages]]);
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
function toPairs(value) {
|
|
306
|
+
if (value instanceof Map)
|
|
307
|
+
return [...value.entries()];
|
|
308
|
+
if (Array.isArray(value)) {
|
|
309
|
+
if (value.length >= 2 && keyString(value[0]) !== undefined) {
|
|
310
|
+
const pairs = [];
|
|
311
|
+
for (let index = 0; index + 1 < value.length; index += 2)
|
|
312
|
+
pairs.push([value[index], value[index + 1]]);
|
|
313
|
+
return pairs;
|
|
314
|
+
}
|
|
315
|
+
return value.flatMap((entry) => {
|
|
316
|
+
if (Array.isArray(entry) && entry.length >= 2)
|
|
317
|
+
return [[entry[0], entry[1]]];
|
|
318
|
+
if (isRecord(entry)) {
|
|
319
|
+
const streamName = entry.name ?? entry.stream;
|
|
320
|
+
const entries = entry.messages ?? entry.entries;
|
|
321
|
+
if (streamName !== undefined && entries !== undefined)
|
|
322
|
+
return [[streamName, entries]];
|
|
323
|
+
}
|
|
324
|
+
return [];
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (isRecord(value)) {
|
|
328
|
+
if (Array.isArray(value.streams))
|
|
329
|
+
return toPairs(value.streams);
|
|
330
|
+
if (Array.isArray(value.messages))
|
|
331
|
+
return [[value.stream ?? "stream", value.messages]];
|
|
332
|
+
return Object.entries(value);
|
|
333
|
+
}
|
|
334
|
+
return [];
|
|
335
|
+
}
|
|
336
|
+
function toEntries(value) {
|
|
337
|
+
if (Array.isArray(value)) {
|
|
338
|
+
if (value.length >= 2 &&
|
|
339
|
+
keyString(value[0]) !== undefined &&
|
|
340
|
+
!Array.isArray(value[0])) {
|
|
341
|
+
const entries = [];
|
|
342
|
+
for (let index = 0; index + 1 < value.length; index += 2)
|
|
343
|
+
entries.push([value[index], value[index + 1]]);
|
|
344
|
+
return entries;
|
|
345
|
+
}
|
|
346
|
+
return value;
|
|
347
|
+
}
|
|
348
|
+
if (value instanceof Map)
|
|
349
|
+
return [...value.entries()];
|
|
350
|
+
if (isRecord(value)) {
|
|
351
|
+
if (Array.isArray(value.messages))
|
|
352
|
+
return value.messages;
|
|
353
|
+
if (Array.isArray(value.entries))
|
|
354
|
+
return value.entries;
|
|
355
|
+
}
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
function toEntry(value) {
|
|
359
|
+
if (Array.isArray(value))
|
|
360
|
+
return [keyString(value[0]), value[1]];
|
|
361
|
+
if (value instanceof Map) {
|
|
362
|
+
const [id, fields] = value.entries().next().value ?? [];
|
|
363
|
+
return [keyString(id), fields];
|
|
364
|
+
}
|
|
365
|
+
if (isRecord(value)) {
|
|
366
|
+
const id = value.id;
|
|
367
|
+
return [keyString(id), value.message ?? value.fields];
|
|
368
|
+
}
|
|
369
|
+
return [undefined, undefined];
|
|
370
|
+
}
|
|
371
|
+
function getField(fields, name) {
|
|
372
|
+
if (fields instanceof Map) {
|
|
373
|
+
for (const [key, value] of fields) {
|
|
374
|
+
if (keyString(key) === name)
|
|
375
|
+
return value;
|
|
376
|
+
}
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
if (Array.isArray(fields)) {
|
|
380
|
+
const index = fields.findIndex((key) => keyString(key) === name);
|
|
381
|
+
return index < 0 ? undefined : fields[index + 1];
|
|
382
|
+
}
|
|
383
|
+
return isRecord(fields) ? fields[name] : undefined;
|
|
384
|
+
}
|
|
385
|
+
function keyString(value) {
|
|
386
|
+
if (typeof value === "string")
|
|
387
|
+
return value;
|
|
388
|
+
if (value instanceof Uint8Array)
|
|
389
|
+
return new TextDecoder().decode(value);
|
|
390
|
+
return undefined;
|
|
391
|
+
}
|
|
392
|
+
function isRecord(value) {
|
|
393
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
394
|
+
}
|
|
395
|
+
function toJobContext(job) {
|
|
396
|
+
return { id: job.id, attempts: job.attempts, enqueuedAt: job.enqueuedAt };
|
|
254
397
|
}
|
|
255
398
|
export function createQueue(options) {
|
|
256
399
|
return new RedisQueue(options);
|
package/dist/queue/queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/queue/queue.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/queue/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,6 +86,7 @@ export declare class RedisRateLimiter implements RateLimiter {
|
|
|
86
86
|
blockUntilReady(identifier: string, timeoutMs: number, request?: RateLimitRequest): Promise<RateLimitResponse>;
|
|
87
87
|
setDynamicLimit(limit: number | false): Promise<void>;
|
|
88
88
|
getDynamicLimit(): Promise<number | null>;
|
|
89
|
+
private readDynamicLimit;
|
|
89
90
|
private runAlgorithm;
|
|
90
91
|
private keysFor;
|
|
91
92
|
private response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/rate-limit/contracts.ts"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/rate-limit/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RedisClientStateError, RedisConfigurationError, RedisConnectionError, RedisProtocolError, RedisTimeoutError, RedisUnavailableError, } from "../core/errors.js";
|
|
2
|
-
import { withTimeout } from "../core/executor.js";
|
|
2
|
+
import { assertPositiveInteger, withTimeout, } from "../core/executor.js";
|
|
3
3
|
import { assertKeyPart, hashIdentifier } from "../core/keys.js";
|
|
4
4
|
export function fixedWindow(limit, windowMs) {
|
|
5
5
|
assertAlgorithmValues(limit, windowMs);
|
|
@@ -41,28 +41,49 @@ export class RedisRateLimiter {
|
|
|
41
41
|
? options.ephemeralCache
|
|
42
42
|
: new Map();
|
|
43
43
|
this.now = options.now ?? Date.now;
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
assertKeyPart(this.prefix, "Rate-limit prefix");
|
|
45
|
+
assertPositiveInteger(this.timeoutMs, "Rate-limit timeout");
|
|
46
|
+
if (this.failureMode !== "open" && this.failureMode !== "closed")
|
|
47
|
+
throw new RedisConfigurationError("Rate-limit failure mode is invalid");
|
|
48
|
+
if (algorithm.kind === "fixed-window" || algorithm.kind === "sliding-window") {
|
|
49
|
+
assertAlgorithmValues(algorithm.limit, algorithm.windowMs);
|
|
50
|
+
}
|
|
51
|
+
else if (algorithm.kind === "token-bucket") {
|
|
52
|
+
assertAlgorithmValues(algorithm.maxTokens ?? algorithm.limit, algorithm.windowMs);
|
|
53
|
+
assertPositiveInteger(algorithm.refillRate ?? 0, "Token bucket refill rate");
|
|
54
|
+
if (algorithm.maxTokens !== undefined && algorithm.maxTokens !== algorithm.limit)
|
|
55
|
+
throw new RedisConfigurationError("Token bucket limit must match its maximum");
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new RedisConfigurationError("Rate-limit algorithm is invalid");
|
|
59
|
+
}
|
|
46
60
|
}
|
|
47
61
|
async limit(identifier, request = {}) {
|
|
48
62
|
assertIdentifier(identifier);
|
|
49
63
|
const weight = request.rate ?? 1;
|
|
50
64
|
if (!Number.isSafeInteger(weight) || weight <= 0)
|
|
51
65
|
throw new RedisConfigurationError("Rate-limit request rate must be positive");
|
|
52
|
-
|
|
66
|
+
if (this.algorithm.kind === "token-bucket" &&
|
|
67
|
+
weight > (this.algorithm.maxTokens ?? this.algorithm.limit))
|
|
68
|
+
throw new RedisConfigurationError("Request rate exceeds the token-bucket maximum");
|
|
69
|
+
const cacheKey = `${identifier}\0${weight}`;
|
|
70
|
+
const cacheEnabled = this.algorithm.kind !== "sliding-window" && !this.options.dynamicLimits;
|
|
71
|
+
const cachedUntil = cacheEnabled ? this.cache?.get(cacheKey) : undefined;
|
|
53
72
|
if (cachedUntil !== undefined) {
|
|
54
73
|
if (cachedUntil > this.now())
|
|
55
74
|
return this.response(false, this.algorithm.limit, 0, cachedUntil, "cache");
|
|
56
|
-
this.cache?.delete(
|
|
75
|
+
this.cache?.delete(cacheKey);
|
|
57
76
|
}
|
|
58
77
|
const started = this.now();
|
|
59
78
|
try {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
const result = await withTimeout(async (signal) => {
|
|
80
|
+
const dynamicLimit = this.options.dynamicLimits
|
|
81
|
+
? await this.readDynamicLimit(signal)
|
|
82
|
+
: null;
|
|
83
|
+
return this.runAlgorithm(identifier, dynamicLimit ?? this.algorithm.limit, weight, started, signal);
|
|
84
|
+
}, this.timeoutMs);
|
|
85
|
+
if (!result.allowed && cacheEnabled && this.cache)
|
|
86
|
+
this.cache.set(cacheKey, result.reset);
|
|
66
87
|
const response = this.response(result.allowed, result.limit, result.remaining, result.reset, result.allowed ? "success" : "limit");
|
|
67
88
|
const pending = this.options.analytics?.record({
|
|
68
89
|
identifier,
|
|
@@ -151,17 +172,29 @@ export class RedisRateLimiter {
|
|
|
151
172
|
const keys = await this.keysFor(identifier, this.now());
|
|
152
173
|
if (keys.length)
|
|
153
174
|
await this.options.redis.execute(["DEL", ...keys]);
|
|
154
|
-
this.cache?.
|
|
175
|
+
for (const key of this.cache?.keys() ?? []) {
|
|
176
|
+
if (key.slice(0, key.lastIndexOf("\0")) === identifier)
|
|
177
|
+
this.cache?.delete(key);
|
|
178
|
+
}
|
|
155
179
|
}
|
|
156
180
|
async blockUntilReady(identifier, timeoutMs, request = {}) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
181
|
+
assertPositiveInteger(timeoutMs, "Rate-limit wait timeout");
|
|
182
|
+
const deadline = Date.now() + timeoutMs;
|
|
183
|
+
let result = await this.limit(identifier, request);
|
|
184
|
+
if (result.success)
|
|
185
|
+
return result;
|
|
186
|
+
while (Date.now() < deadline) {
|
|
187
|
+
const remaining = deadline - Date.now();
|
|
188
|
+
if (remaining <= 0)
|
|
189
|
+
break;
|
|
190
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(Math.max(result.retryAfterMs, 10), remaining)));
|
|
191
|
+
if (Date.now() >= deadline)
|
|
192
|
+
break;
|
|
193
|
+
result = await this.limit(identifier, request);
|
|
160
194
|
if (result.success)
|
|
161
195
|
return result;
|
|
162
|
-
await new Promise((resolve) => setTimeout(resolve, Math.min(Math.max(result.retryAfterMs, 10), Math.max(10, deadline - this.now()))));
|
|
163
196
|
}
|
|
164
|
-
return
|
|
197
|
+
return result;
|
|
165
198
|
}
|
|
166
199
|
async setDynamicLimit(limit) {
|
|
167
200
|
if (!this.options.dynamicLimits)
|
|
@@ -178,10 +211,10 @@ export class RedisRateLimiter {
|
|
|
178
211
|
async getDynamicLimit() {
|
|
179
212
|
if (!this.options.dynamicLimits)
|
|
180
213
|
return null;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
]);
|
|
214
|
+
return this.readDynamicLimit();
|
|
215
|
+
}
|
|
216
|
+
async readDynamicLimit(signal) {
|
|
217
|
+
const value = await this.options.redis.execute(["GET", `${this.prefix}:dynamic-limit`], signal ? { signal } : undefined);
|
|
185
218
|
if (value === null)
|
|
186
219
|
return null;
|
|
187
220
|
const limit = Number(value);
|
|
@@ -189,7 +222,7 @@ export class RedisRateLimiter {
|
|
|
189
222
|
throw new RedisProtocolError("Invalid dynamic rate-limit response");
|
|
190
223
|
return limit;
|
|
191
224
|
}
|
|
192
|
-
async runAlgorithm(identifier, limit, weight, now) {
|
|
225
|
+
async runAlgorithm(identifier, limit, weight, now, signal) {
|
|
193
226
|
const digest = await hashIdentifier(identifier);
|
|
194
227
|
if (this.algorithm.kind === "fixed-window") {
|
|
195
228
|
const start = Math.floor(now / this.algorithm.windowMs) * this.algorithm.windowMs;
|
|
@@ -197,7 +230,7 @@ export class RedisRateLimiter {
|
|
|
197
230
|
const value = await this.options.redis.eval(FIXED_WINDOW_SCRIPT, {
|
|
198
231
|
keys: [`${this.prefix}:${digest}:${start}`],
|
|
199
232
|
arguments: [String(weight), String(reset - now)],
|
|
200
|
-
});
|
|
233
|
+
}, { signal });
|
|
201
234
|
const count = parseInteger(value, "fixed-window");
|
|
202
235
|
return {
|
|
203
236
|
allowed: count <= limit,
|
|
@@ -219,7 +252,7 @@ export class RedisRateLimiter {
|
|
|
219
252
|
String(now - start),
|
|
220
253
|
String(start + this.algorithm.windowMs - now),
|
|
221
254
|
],
|
|
222
|
-
});
|
|
255
|
+
}, { signal });
|
|
223
256
|
if (!Array.isArray(value) || value.length < 2)
|
|
224
257
|
throw new RedisProtocolError("Invalid sliding-window response");
|
|
225
258
|
const weighted = Number(value[1]);
|
|
@@ -239,7 +272,7 @@ export class RedisRateLimiter {
|
|
|
239
272
|
String(weight),
|
|
240
273
|
String(now),
|
|
241
274
|
],
|
|
242
|
-
});
|
|
275
|
+
}, { signal });
|
|
243
276
|
if (!Array.isArray(value) || value.length < 3)
|
|
244
277
|
throw new RedisProtocolError("Invalid token-bucket response");
|
|
245
278
|
const allowed = Number(value[0]) === 1;
|
|
@@ -278,7 +311,7 @@ export class RedisRateLimiter {
|
|
|
278
311
|
}
|
|
279
312
|
const FIXED_WINDOW_SCRIPT = `local current = redis.call("INCRBY", KEYS[1], ARGV[1]) if current == tonumber(ARGV[1]) then redis.call("PEXPIRE", KEYS[1], ARGV[2]) end return current`;
|
|
280
313
|
const SLIDING_WINDOW_SCRIPT = `local current = redis.call("INCRBY", KEYS[1], ARGV[1]) if current == tonumber(ARGV[1]) then redis.call("PEXPIRE", KEYS[1], ARGV[2]) redis.call("PEXPIRE", KEYS[2], ARGV[2]) end local previous = tonumber(redis.call("GET", KEYS[2]) or "0") local weighted = previous * ((tonumber(ARGV[2]) - tonumber(ARGV[3])) / tonumber(ARGV[2])) + current return {current, weighted}`;
|
|
281
|
-
const TOKEN_BUCKET_SCRIPT = `local state = redis.call("HMGET", KEYS[1], "tokens", "updated") local tokens = tonumber(state[1]) or tonumber(ARGV[1]) local updated = tonumber(state[2]) or tonumber(ARGV[5]) local elapsed = math.max(0, tonumber(ARGV[5]) - updated) local refill = elapsed * tonumber(ARGV[2]) / tonumber(ARGV[3]) tokens = math.min(tonumber(ARGV[1]), tokens + refill) local requested = tonumber(ARGV[4]) local allowed = 0 if tokens >= requested then tokens = tokens - requested allowed = 1 end local reset = tonumber(ARGV[5]) + math.ceil(
|
|
314
|
+
const TOKEN_BUCKET_SCRIPT = `local state = redis.call("HMGET", KEYS[1], "tokens", "updated") local tokens = tonumber(state[1]) or tonumber(ARGV[1]) local updated = tonumber(state[2]) or tonumber(ARGV[5]) local elapsed = math.max(0, tonumber(ARGV[5]) - updated) local refill = elapsed * tonumber(ARGV[2]) / tonumber(ARGV[3]) tokens = math.min(tonumber(ARGV[1]), tokens + refill) local requested = tonumber(ARGV[4]) local allowed = 0 local needed = requested - tokens if tokens >= requested then tokens = tokens - requested allowed = 1 needed = math.max(0, 1 - tokens) end local reset = tonumber(ARGV[5]) + math.ceil(needed * tonumber(ARGV[3]) / tonumber(ARGV[2])) redis.call("HSET", KEYS[1], "tokens", tokens, "updated", ARGV[5]) redis.call("PEXPIRE", KEYS[1], ARGV[3]) return {allowed, tokens, reset}`;
|
|
282
315
|
function assertIdentifier(identifier) {
|
|
283
316
|
if (!identifier.trim() || identifier.length > 512)
|
|
284
317
|
throw new RedisConfigurationError("Rate-limit identifier must be between one and 512 characters");
|