You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix: add blockingTimeout option for blocking commands
* docs: update readme with blockingTimeout
* fix: resolve blocking commands with null on timeout instead of hanging
- Blocking commands (BLPOP, BRPOP, BZPOPMIN, XREAD, etc.) now resolve
with `null` when their timeout expires without a response, matching
Redis behavior and preventing indefinite hangs during undetectable
network failures
- Added `blockingTimeout` option as a safety net for commands that
block forever (timeout=0 / BLOCK 0)
- Automatically extracts and tracks timeout from command arguments,
adding a 100ms grace period for finite timeouts
- Protects commands in both offline queue and command queue with
absolute deadline tracking
- Simplified setBlockingTimeout API to resolve with null (no callback,
no error rejection)
* refactor(command): move blocking timeout extraction to Command class
* fix: blocking timeout reamde and add more unit tests
* test: add more unit and functional tests
* feat: add configurable blockingTimeoutGrace option
---------
Co-authored-by: Pavel Pashov <pavel.pashov@redis.com>
Copy file name to clipboardExpand all lines: README.md
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -798,6 +798,20 @@ const redis = new Redis({
798
798
799
799
Set maxRetriesPerRequest to `null` to disable this behavior, and every command will wait forever until the connection is alive again (which is the default behavior before ioredis v4).
800
800
801
+
### Blocking Command Timeout
802
+
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
+
805
+
For commands with a finite timeout (e.g., `blpop("key", 5)`), ioredis automatically sets a client-side deadline based on the command's timeout plus a small grace period. If no reply arrives before the deadline, the command resolves with `null`—the same value Redis returns when a blocking command times out normally.
806
+
807
+
For commands that intentionally block forever (e.g., `timeout = 0` or `BLOCK 0`), you can provide a safety net via the optional `blockingTimeout` option (milliseconds):
808
+
809
+
```javascript
810
+
constredis=newRedis({
811
+
blockingTimeout:30000, // Resolve with null after 30 seconds when timeout=0/BLOCK 0
812
+
});
813
+
```
814
+
801
815
### Reconnect on Error
802
816
803
817
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:
0 commit comments