Reputation: 365
I am using node-redis version 3.0.2
. However, I was checking how my website will respond if the Redis server is down. I have this request handler where It calls a function that checks first if the provided key is in Redis, else make a database call and then save the fetched data in Redis.
const GetByPriority = model => async (req, res) => {
let { page=1, size=9 } = req.query;
size = parseInt(size);
page = parseInt(page);
try {
const doc = await SetOrGetCompanyCache(`companies-${page}-${size}`, async () => {
const query = await model
.find({})
.limit(size*1)
.skip((page-1)*size)
.sort({ p: -1, _id:1 })
.lean()
.exec()
return query;
})
if (!doc)
{
return res.status(404).end()
}
res.status(200).json({page:page, size:size, data: doc })
} catch (e) {
console.error(e)
res.status(400).end()
}
}
The problem is when the Redis server is down, there does not seem to be an error returned by redisClient
's get method. I mean I don't get why it did not log the error. Also, It did not return InternalServerError
.
export function SetOrGetCompanyCache (key, callback) {
return new Promise((resolve, reject)=>{
redisClient.get(key, async (error,data)=>{
if(error)
{
console.log(error) //It does not get here
return reject(createError.InternalServerError('Caching Error'))
}
//Cache hit
if(data != null)
{
return resolve(JSON.parse(data))
}
//Cache miss
//callback() --> MongoDB query
const queryData = await callback();
if(!queryData)
{
return reject(createError[404])
}
redisClient.setex(key,COMPANY_QUERY_EXP,JSON.stringify(queryData))
resolve(queryData)
})
})
}
It only logged the following snippet
Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379
I believe this is because I added the following listener inside redisClient
file
redisClient.on('error', (err)=>{
console.error(err.message)
})
The problem now is that the set
method does not return any error indicating that the Redis server is down, hence I can't even make the server perform a normal database call in that case.
Upvotes: 1
Views: 9149
Reputation: 365
I asked the redis
community on discord and they mentioned that I should set enable-offline-queue
to false
inside redis-client
It should look like this
export const redisClient = createClient({
port: process.env.REDIS_PORT,
host: process.env.REDIS_HOST,
//In order to turn off queuing commands and get an error if we couldn't connect to the redis server
enable_offline_queue: false
});
As they mentioned
In Node Redis, if you handle add the on('error') stuff it will queue up your commands and then in the background try to reconnect. When it does reconnect, it will then run the queued commands. [7:30 PM] It actually follows a retry_strategy to attempt to reconnect. You can read all about it on the old README at https://www.npmjs.com/package/redis/v/3.1.2 npm redis A modern, high performance Redis client. Latest version: 4.0.4, last published: 24 days ago. Start using redis in your project by running
npm i redis
. There are 8235 other projects in the npm registry using redis.[7:31 PM] You need to set the enable_offline_queue option to false to turn off this queueing and get an error.
Upvotes: 2