Skip to content

Ioredis: When reconnecting redis via connect() , calling connect doesn’t reset retry times to 0

I have following options set when connecting to Redis

var client = new Redis({
  port: 63xx, // Redis port
  host: REDISHOST, // Redis host
  family: 4, // 4 (IPv4) or 6 (IPv6)
  db: 0,
  lazyConnect: true,
  // The milliseconds before a timeout occurs during the initial connection to the Redis server.
  connectTimeout: 3000,

  retryStrategy: function (times) {

    if (times > 3) {
      logger.error("redisRetryError", 'Redis reconnect exhausted after 3 retries.');
      return null;
    }

    return 200;

  }

}); 

Later on, I am exporting this client throughout project for redis queries. The issue is when Request 1 comes and there is some issue with redis, it tries to auto-connect for 4 times(+1 for initial try). Then throws error which is handled. So for now times variable(used in retrystrategy()) will have 4 as value.

Next time when Request 2 comes and we see redis is disconnected so we reconnect using client.connect() method:

static async getData(key) {

        try {

            // if connection is ended then we are trying to reconnect it.
            if (client.status === 'end') {
                await logger.warning(`reconnectingRedis`, 'Redis is not connected. Trying to reconnect to Redis!');
                await client.connect();
            }

            let output = await client.get(key);

            return JSON.parse(output);

        } catch (error) {
            ApiError.throw(error, errorCode.REDIS_GET_ERROR_CODE);
        }

    }

this time redis tries to reconnect but it doesn’t resets the times variable used in retrystrategy(), So this variable now have 5. And if this attempt too fails, retrystrategy() just throws error as times > 3

So effectively Request 1 gets 4 tries and Request 2 gets only 1

How can I fix this, So that Request 2 also gets 4 tries ?

Answer

To fix this issue I changed retryStrategy function used while creating redis in following way:

retryStrategy: function (times) {

    if (times % 4 ==0) { 
      logger.error("redisRetryError", 'Redis reconnect exhausted after 3 retries.');
      return null;
    }

    return 200;

  }

Notice I took mod 4 of times variable and Doing so we will always get a value in range of 0-3.

So for request 2 when times variable has 5, its mod 4 will give 1 and will be tried, next time times will be 6, So mode 4 is 2 and will be tried and so on. Till it becomes 8, In this case, mod 4 will give 0 and retry stops.

This fixed the issue for me.