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...");
});
One thing that is interesting is the fact that the 'end' event gets emitted. Why?
Due to the single-threaded nature of Redis, it is not possible to kill a client connection while it is executing a command. From the client point of view, the connection can never be closed in the middle of the execution of a command.
Continuously opening connections without closing is not a good practice. This will not only consume your resources but may also lead to program crash. The maximum number of file descriptors that you can open simultaneously is 1024.
The most common reason for the connection refused error is that the Redis-Server is not started. Redis server should be started to use the Redis client after its installation. It can be done with the following command. Also to run Redis in the background, following command could be used.
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#options-object-properties
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;
}
});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With