I am using Node Redis with this config:
import redis from "redis";
import { promisify } from "util";
import config from "../../appConfig";
const redisUrl = config.REDIS_URL;
const [host, port] = redisUrl.substr(8).split(":");
const RedisClient = redis.createClient({ host: host, port: Number(port) });
RedisClient.on("error", (err) => {
logger.error(err);
});
const GetAsync = promisify(RedisClient.get).bind(RedisClient);
const SetAsync = promisify(RedisClient.set).bind(RedisClient);
export { RedisClient, GetAsync, SetAsync };
I have some code which first tries reading from Redis and if that fails, tries reading from MongoDB inside a catch block. Something like this:
try {
userId = await GetAsync(idKeyStr);
} catch(err) {
userId = await GetFromMongoDB();
}
My problem is that when the connection fails, the code just gets stuck at userId = await GetAsync(idKeyStr)
. No exception is being thrown so that the code moves into the catch block. The default time till which the client attempts to reconnect is 1 hour. If within that 1 hour, the server comes up, it will reconnect and the request which was stuck will finally get handled. If it doesnt come up, that request will just be stuck for 1 hour.
If I throw an error from the callback for error
event, the application just stops, because of unhandled exception.
I found the retry_strategy
option for the createClient
method here: https://github.com/NodeRedis/node-redis This is the example given on that page:
const 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);
},
});
To throw an error immediately, I modified this to:
const client = redis.createClient({
retry_strategy: function() {
return new Error("The server refused the connection");
},
});
But this stops the retries altogether, so even when the server comes up, the client has stopped connection attempts so it never reconnects.
How can I configure it so that the client continues to reconnect but any issued commands fail fast, so that my other code continues execution?