I’m implementing a cache mechanism on my app using redis. I’m using redis ^4.0.2
.
My app is organized like this:
- index.js
-- routes
-- users.js
-- controllers
-- users.js
-- models
-- user.js
-- db
-- postgres.js
-- redis.js
I would like to implement the cache at the models but I want to create the redis connection in db/redis.js
and export it and have the model requiring it.
This is what db/redis.js
looks like:
const Redis = require('redis');
const redisClient = Redis.createClient();
redisClient.connect();
redisClient.on('connect', function() {
console.log('Redis is Connected!');
});
redisClient.on('error', err => {
console.log('Redis Error ' + err);
});
redisClient.on('end', () => {
console.log('Redis disconnected');
});
redisClient.on('reconnecting', () => {
console.log('Redis reconnecting');
});
module.exports = redisClient;
This is my model:
const postgresClient = require('../db/postgres');
const redisClient = require('../db/redis');
const getAllUsers = (params, callback) => {
console.log('getAllUsers');
const page = params.page || 1;
const count = params.count || 5;
const offset = (page - 1) * count;
const queryStr = `SELECT * FROM users OFFSET ${offset} FETCH NEXT ${count} ROWS ONLY`;
const cacheKey = `users?page=${page}&count=${count}`;
redisClient.get(cacheKey, (error, users) => {
console.log('redisClient.get');
if (error) callback(error);
if (users != null) {
console.log('sending data from cache')
callback(null, JSON.parse(users));
} else {
postgresClient.query(queryStr, (err, res) => {
console.log('querying db and setting cache')
if (err) callback(err);
redisClient.setex(cacheKey, DEFAULT_EXPIRATION, JSON.stringify(res.rows))
callback(null, res.rows);
})
}
}
}
When I run the server and make a request to the endpoint that uses this model, the console.log('getAllUsers');
runs but console.log('redisClient.get');
doesn’t.
It seems like the redis client get callback
never executes and I wonder why.
Any help or advice is welcome. Thanks in advance.
2
Answers
It looks to me as if you’re reinventing the world. If what you want is just a cache, have you considered using a package for that? I’ve had good luck with this one:
https://www.npmjs.com/package/cacheman-redis
If that doesn’t work for you, it looks like the latest version of the redis npm recommends using promises, like so:
If you just can’t use await, then I’d suggest using then. So, instead of using
redisClient.get(key, callback)
you could useThat being said, I strongly recommend looking at
cacheman-redis
and also becoming familiar with async/await functions and promises. Each will simplify your code greatly.redisClient.connect();
does not really wait before connection succeeds. If you are running the commands before it has a successful connection it wouldn’t work. You need to wait before it’s connected and then it’s safe to run Redis commands.You can remove
redisClient.connect();
from yourredis.js
file and use it in index.js where you connect it.example-source
Also, I’d recommend you to connect Redis at first and when successful then start the server.