redis/ioredis

Blocking not working properly in case of reconnections

Open

#1,285 opened on Feb 5, 2021

View on GitHub
 (11 comments) (1 reaction) (0 assignees)TypeScript (1,069 forks)batch import
help wantedneed reproduce

Repository metrics

Stars
 (12,302 stars)
PR merge metrics
 (Avg merge 3d 5h) (5 merged PRs in 30d)

Description

There is this older issue https://github.com/luin/ioredis/issues/610 also created by me. But since this is rather important I would like to create a new one with a very specific code to reproduce the issue easily so that it can be resolved once and for all :).

This is the code:


async function main() {
  const client = new Redis();

  client.on('error', err => console.log('Redis error', err));
  client.on('reconnecting', msg => console.log('Redis reconnecting...', msg));
  client.on('close', () => console.log('Redis closed...'));
  client.on('connect', () => console.log('Redis connected...'));

  while (true) {
    try {
      console.log('going to block');
      const value = await client.brpoplpush('a', 'b', 4);
      console.log('unblocked', value);
    } catch (err) {
      console.error('ERROR', err);
    }
  }
}

main();

How to reproduce

Just run the code above with a local redis server. The while loop will run forever outputting the following:

going to block
Redis connected...
unblocked null
going to block
unblocked null
going to block
unblocked null
going to block

It just blocks for up to 4 seconds, then unblocks, and so on. Now, while this program is running just stop the redis server, wait a couple of seconds and start it again:

Output would look like this:

Redis closed...
Redis reconnecting... 50
Redis connected...
Redis closed...
Redis reconnecting... 100
Redis error Error: connect ECONNREFUSED 127.0.0.1:6379
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379
}
...
...
Redis closed...
Redis reconnecting... 700
Redis connected...

And thats all. The while loop will not continue running as if the call to client.brpoplpush has hanged forever.

Expected results

I expect that as soon as the the client disconnects the call to client.brpoplpush rejects the promise with a connection error. Client code should be able to handle calling again to this blocking command.

I am a bit surprised no one else has reported this issue, I wonder if there is some wrong expectation from my side or if I am using the library incorrectly, if so please let me know since this issue is quite severe for users of Bull/BullMQ libraries.

Contributor guide