@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.
Files changed (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/bullmq/adapter.d.ts +2 -0
  3. package/dist/bullmq/adapter.d.ts.map +1 -1
  4. package/dist/bullmq/adapter.js +13 -3
  5. package/dist/bullmq/adapter.js.map +1 -1
  6. package/dist/cache/cache.d.ts.map +1 -1
  7. package/dist/cache/cache.js +12 -2
  8. package/dist/cache/cache.js.map +1 -1
  9. package/dist/core/codec.d.ts.map +1 -1
  10. package/dist/core/codec.js +5 -1
  11. package/dist/core/codec.js.map +1 -1
  12. package/dist/core/executor.d.ts +1 -1
  13. package/dist/core/executor.d.ts.map +1 -1
  14. package/dist/core/executor.js +22 -3
  15. package/dist/core/executor.js.map +1 -1
  16. package/dist/core/hooks.d.ts +5 -0
  17. package/dist/core/hooks.d.ts.map +1 -0
  18. package/dist/core/hooks.js +23 -0
  19. package/dist/core/hooks.js.map +1 -0
  20. package/dist/ioredis/executor.d.ts +2 -2
  21. package/dist/ioredis/executor.d.ts.map +1 -1
  22. package/dist/ioredis/executor.js +6 -6
  23. package/dist/ioredis/executor.js.map +1 -1
  24. package/dist/ioredis/pubsub.d.ts +1 -0
  25. package/dist/ioredis/pubsub.d.ts.map +1 -1
  26. package/dist/ioredis/pubsub.js +40 -12
  27. package/dist/ioredis/pubsub.js.map +1 -1
  28. package/dist/locks/locks.d.ts.map +1 -1
  29. package/dist/locks/locks.js +14 -4
  30. package/dist/locks/locks.js.map +1 -1
  31. package/dist/node/client.d.ts.map +1 -1
  32. package/dist/node/client.js +28 -20
  33. package/dist/node/client.js.map +1 -1
  34. package/dist/node/pool.d.ts +8 -2
  35. package/dist/node/pool.d.ts.map +1 -1
  36. package/dist/node/pool.js +53 -27
  37. package/dist/node/pool.js.map +1 -1
  38. package/dist/node/pubsub.d.ts.map +1 -1
  39. package/dist/node/pubsub.js +37 -5
  40. package/dist/node/pubsub.js.map +1 -1
  41. package/dist/pubsub/pubsub.d.ts.map +1 -1
  42. package/dist/pubsub/pubsub.js +9 -1
  43. package/dist/pubsub/pubsub.js.map +1 -1
  44. package/dist/queue/index.d.ts +1 -1
  45. package/dist/queue/index.d.ts.map +1 -1
  46. package/dist/queue/index.js.map +1 -1
  47. package/dist/queue/queue.d.ts +20 -0
  48. package/dist/queue/queue.d.ts.map +1 -1
  49. package/dist/queue/queue.js +216 -73
  50. package/dist/queue/queue.js.map +1 -1
  51. package/dist/rate-limit/contracts.d.ts +1 -0
  52. package/dist/rate-limit/contracts.d.ts.map +1 -1
  53. package/dist/rate-limit/contracts.js +59 -26
  54. package/dist/rate-limit/contracts.js.map +1 -1
  55. package/docs/adapters.md +3 -1
  56. package/docs/queues.md +16 -0
  57. package/package.json +1 -1
@@ -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 required");
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 ((enqueueOptions.delayMs ?? 0) > 0) {
36
+ if (delayMs > 0) {
25
37
  await this.options.redis.execute([
26
38
  "ZADD",
27
39
  this.delayedKey,
28
- String(Date.now() + (enqueueOptions.delayMs ?? 0)),
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().finally(() => {
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
- const due = await this.queue.redis.execute([
150
- "ZRANGEBYSCORE",
151
- this.queue.delayedKey,
152
- "-inf",
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
- const job = this.queue.decode(entry.payload);
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 (_error) {
194
- await this.queue.redis.execute([
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
- await this.queue.redis.execute([
212
- "XADD",
213
- this.queue.streamKey,
214
- "*",
215
- "payload",
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
- for (const rawEntry of streams[1]) {
238
- if (!Array.isArray(rawEntry) ||
239
- typeof rawEntry[0] !== "string" ||
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 fields = rawEntry[1];
243
- const payloadIndex = fields.indexOf("payload");
244
- const payload = payloadIndex >= 0 ? fields[payloadIndex + 1] : undefined;
245
- if (typeof payload === "string")
246
- result.push({ id: rawEntry[0], payload });
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 (!Array.isArray(value) || !Array.isArray(value[1]))
252
- return [];
253
- return parseStreamResponse([["recovered", value[1]]]);
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);
@@ -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":"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"}
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
- if (!this.prefix.trim())
45
- throw new RedisConfigurationError("Rate-limit prefix is required");
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
- const cachedUntil = this.cache?.get(identifier);
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(identifier);
75
+ this.cache?.delete(cacheKey);
57
76
  }
58
77
  const started = this.now();
59
78
  try {
60
- const dynamicLimit = this.options.dynamicLimits
61
- ? await this.getDynamicLimit()
62
- : null;
63
- const result = await withTimeout(() => this.runAlgorithm(identifier, dynamicLimit ?? this.algorithm.limit, weight, started), this.timeoutMs);
64
- if (!result.allowed && this.cache)
65
- this.cache.set(identifier, result.reset);
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?.delete(identifier);
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
- const deadline = this.now() + timeoutMs;
158
- while (this.now() <= deadline) {
159
- const result = await this.limit(identifier, request);
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 this.limit(identifier, request);
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
- const value = await this.options.redis.execute([
182
- "GET",
183
- `${this.prefix}:dynamic-limit`,
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((requested - tokens) * 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}`;
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");