ioredis 5.9.0 → 5.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/built/Redis.js +13 -8
- package/built/redis/RedisOptions.d.ts +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -802,16 +802,22 @@ Set maxRetriesPerRequest to `null` to disable this behavior, and every command w
|
|
|
802
802
|
|
|
803
803
|
ioredis can apply a client-side timeout to blocking commands (such as `blpop`, `brpop`, `bzpopmin`, `bzmpop`, `blmpop`, `xread`, `xreadgroup`, etc.). This protects against scenarios where the TCP connection becomes a zombie (e.g., due to a silent network failure like a Docker network disconnect) and Redis never replies.
|
|
804
804
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
805
|
+
This feature is **opt-in**. It is **disabled by default** and is only enabled
|
|
806
|
+
when `blockingTimeout` is set to a positive number of milliseconds. If
|
|
807
|
+
`blockingTimeout` is omitted, `0`, or negative (for example `-1`), ioredis
|
|
808
|
+
does not arm any client-side timeouts for blocking commands and their
|
|
809
|
+
behavior matches Redis exactly.
|
|
808
810
|
|
|
809
811
|
```javascript
|
|
810
812
|
const redis = new Redis({
|
|
811
|
-
blockingTimeout: 30000, //
|
|
813
|
+
blockingTimeout: 30000, // Enable blocking timeout protection
|
|
812
814
|
});
|
|
813
815
|
```
|
|
814
816
|
|
|
817
|
+
When enabled:
|
|
818
|
+
- For commands with a finite timeout (e.g., `blpop("key", 5)`), ioredis sets a client-side deadline based on the command's timeout plus a small grace period (`blockingTimeoutGrace`, default 100ms). If no reply arrives before the deadline, the command resolves with `null`—the same value Redis returns when a blocking command times out normally.
|
|
819
|
+
- For commands that block forever (e.g., `timeout = 0` or `BLOCK 0`), the `blockingTimeout` value is used as a safety net.
|
|
820
|
+
|
|
815
821
|
### Reconnect on Error
|
|
816
822
|
|
|
817
823
|
Besides auto-reconnect when the connection is closed, ioredis supports reconnecting on certain Redis errors using the `reconnectOnError` option. Here's an example that will reconnect when receiving `READONLY` error:
|
package/built/Redis.js
CHANGED
|
@@ -325,7 +325,7 @@ class Redis extends Commander_1.default {
|
|
|
325
325
|
* @ignore
|
|
326
326
|
*/
|
|
327
327
|
sendCommand(command, stream) {
|
|
328
|
-
var _a, _b
|
|
328
|
+
var _a, _b;
|
|
329
329
|
if (this.status === "wait") {
|
|
330
330
|
this.connect().catch(lodash_1.noop);
|
|
331
331
|
}
|
|
@@ -379,11 +379,11 @@ class Redis extends Commander_1.default {
|
|
|
379
379
|
stream: stream,
|
|
380
380
|
select: this.condition.select,
|
|
381
381
|
});
|
|
382
|
-
// For blocking commands
|
|
383
|
-
//
|
|
384
|
-
//
|
|
382
|
+
// For blocking commands in the offline queue, arm a client-side timeout
|
|
383
|
+
// only when blockingTimeout is configured. Without this option, queued
|
|
384
|
+
// blocking commands may wait indefinitely on a dead connection.
|
|
385
385
|
if (Command_1.default.checkFlag("BLOCKING_COMMANDS", command.name)) {
|
|
386
|
-
const offlineTimeout =
|
|
386
|
+
const offlineTimeout = this.getConfiguredBlockingTimeout();
|
|
387
387
|
if (offlineTimeout !== undefined) {
|
|
388
388
|
command.setBlockingTimeout(offlineTimeout);
|
|
389
389
|
}
|
|
@@ -392,7 +392,7 @@ class Redis extends Commander_1.default {
|
|
|
392
392
|
else {
|
|
393
393
|
// @ts-expect-error
|
|
394
394
|
if (debug.enabled) {
|
|
395
|
-
debug("write command[%s]: %d -> %s(%o)", this._getDescription(), (
|
|
395
|
+
debug("write command[%s]: %d -> %s(%o)", this._getDescription(), (_b = this.condition) === null || _b === void 0 ? void 0 : _b.select, command.name, command.args);
|
|
396
396
|
}
|
|
397
397
|
if (stream) {
|
|
398
398
|
if ("isPipeline" in stream && stream.isPipeline) {
|
|
@@ -435,6 +435,11 @@ class Redis extends Commander_1.default {
|
|
|
435
435
|
if (!Command_1.default.checkFlag("BLOCKING_COMMANDS", command.name)) {
|
|
436
436
|
return undefined;
|
|
437
437
|
}
|
|
438
|
+
// Feature is opt-in: only enabled when blockingTimeout is set to a positive number
|
|
439
|
+
const configuredTimeout = this.getConfiguredBlockingTimeout();
|
|
440
|
+
if (configuredTimeout === undefined) {
|
|
441
|
+
return undefined;
|
|
442
|
+
}
|
|
438
443
|
const timeout = command.extractBlockingTimeout();
|
|
439
444
|
if (typeof timeout === "number") {
|
|
440
445
|
if (timeout > 0) {
|
|
@@ -442,11 +447,11 @@ class Redis extends Commander_1.default {
|
|
|
442
447
|
return timeout + ((_a = this.options.blockingTimeoutGrace) !== null && _a !== void 0 ? _a : RedisOptions_1.DEFAULT_REDIS_OPTIONS.blockingTimeoutGrace);
|
|
443
448
|
}
|
|
444
449
|
// Command has timeout=0 (block forever), use blockingTimeout option as safety net
|
|
445
|
-
return
|
|
450
|
+
return configuredTimeout;
|
|
446
451
|
}
|
|
447
452
|
if (timeout === null) {
|
|
448
453
|
// No BLOCK option found (e.g., XREAD without BLOCK), use blockingTimeout as safety net
|
|
449
|
-
return
|
|
454
|
+
return configuredTimeout;
|
|
450
455
|
}
|
|
451
456
|
return undefined;
|
|
452
457
|
}
|
|
@@ -12,13 +12,15 @@ export interface CommonRedisOptions extends CommanderOptions {
|
|
|
12
12
|
*/
|
|
13
13
|
commandTimeout?: number;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Enables client-side timeout protection for blocking commands when set
|
|
16
|
+
* to a positive number. If `blockingTimeout` is undefined, `0`, or
|
|
17
|
+
* negative (e.g. `-1`), the protection is disabled and no client-side
|
|
18
|
+
* timers are installed for blocking commands.
|
|
17
19
|
*/
|
|
18
20
|
blockingTimeout?: number;
|
|
19
21
|
/**
|
|
20
|
-
* Grace period (ms) added to blocking command timeouts
|
|
21
|
-
*
|
|
22
|
+
* Grace period (ms) added to blocking command timeouts. Only used when
|
|
23
|
+
* `blockingTimeout` is a positive number. Defaults to 100ms.
|
|
22
24
|
*/
|
|
23
25
|
blockingTimeoutGrace?: number;
|
|
24
26
|
/**
|