8

I have a valid server configuration in which redis can't be accessed, but the server can function correctly (I simply strip away features when redis can't be found).

However, I can't manage the connection errors well. I'd like to know when a connection error fails and shutdown the client in that case.

I've found that the connection retry will never stop. And quit() is actually swallowed - "Queueing quit for next server connection." - when called.

Is there a way to kill the client in the case where no connection can be established?

var redis = require("redis"),
    client = redis.createClient();

client.on("error", function(err) {
    logme.error("Bonk. The worker framework cannot connect to redis, which might be ok on a dev server!");
    logme.error("Resque error : "+err);
    client.quit();
});

client.on("idle", function(err) {
    logme.error("Redis queue is idle. Shutting down...");
});

client.on("end", function(err) {
    logme.error("Redis is shutting down. This might be ok if you chose not to run it in your dev environment");
});

client.on("ready", function(err) {
    logme.info("Redis up! Now connecting the worker queue client...");
});
  • ERROR - Resque error : Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
  • ERROR - Redis is shutting down. This might be ok if you chose not to run it in your dev environment
  • ERROR - Resque error : Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
  • ERROR - Resque error : Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
  • ERROR - Resque error : Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
  • ERROR - Resque error : Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED

One thing that is interesting is the fact that the 'end' event gets emitted. Why?

Greg
  • 2,559
  • 4
  • 28
  • 46

2 Answers2

8

For v3.1.2 of the library

The right way to have control on the client's reconnect behaviour is to use a retry_strategy.

Upon disconnection the redisClient will try to reconnect as per the default behaviour. The default behaviour can be overridden by providing a retry_strategy while creating the client.

Example usage of some fine grained control from the documentation.

var client = redis.createClient({
    retry_strategy: function (options) {
        if (options.error && options.error.code === 'ECONNREFUSED') {
            // End reconnecting on a specific error and flush all commands with
            // a individual error
            return new Error('The server refused the connection');
        }
        if (options.total_retry_time > 1000 * 60 * 60) {
            // End reconnecting after a specific timeout and flush all commands
            // with a individual error
            return new Error('Retry time exhausted');
        }
        if (options.attempt > 10) {
            // End reconnecting with built in error
            return undefined;
        }
        // reconnect after
        return Math.min(options.attempt * 100, 3000);
    }
});

Ref: https://www.npmjs.com/package/redis/v/3.1.2

For the purpose of killing the client when the connection is lost, we could use the following retry_strategy.

var client = redis.createClient({
    retry_strategy: function (options) {
        return undefined;
    }
});

Update June 2022 (Redis v4.1.0)

The original answer was for an earlier version of Redis client. Since v4 things have changed in the client configuration. Specifically, the retry_strategy is now called reconnectStrategy and is nested under the socket configuration option for createClient.

Dhwani Katagade
  • 939
  • 11
  • 22
1

You might want to just forcibly end the connection to redis on error with client.end() rather than using client.quit() which waits for the completion of all outstanding requests and then sends the QUIT command which as you know requires a working connection with redis to complete.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • 1
    end() doesn't work for very similar reasons. even after the client has been ended, connection errors are thrown. it's worse now though since the client is gone, node will crash. the root cause seems to be the retries. – Greg May 03 '12 at 13:31