Estoy implementando un mecanismo de caché en mi aplicación usando redis. Estoy usando redis ^4.0.2 .
Mi aplicación está organizada así:
- index.js -- routes -- users.js -- controllers -- users.js -- models -- user.js -- db -- postgres.js -- redis.js Me gustaría implementar el caché en los modelos, pero quiero crear la conexión redis en db/redis.js y exportarla y tener el modelo que la requiera.
Así es como se ve db/redis.js :
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;Este es mi modelo:
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); }) } } } Cuando ejecuto el servidor y hago una solicitud al punto final que usa este modelo, el console.log('getAllUsers'); se ejecuta pero console.log('redisClient.get'); no.
Parece que la devolución de get callback del cliente redis nunca se ejecuta y me pregunto por qué.
Cualquier ayuda o consejo es bienvenido. Gracias por adelantado.
Me parece que estás reinventando el mundo. Si lo que quiere es solo un caché, ¿ha considerado usar un paquete para eso? He tenido buena suerte con este:
https://www.npmjs.com/package/cacheman-redis
Si eso no funciona para usted, parece que la última versión de redis npm recomienda usar promesas, así:
const value = await redisClient.get(`key`); if (!value) { // query postgres and set the value. } Si simplemente no puede usar await, le sugiero que use then. Entonces, en lugar de usar redisClient.get(key, callback) , podría usar
redisClient.get(key).then(successCallback).catch(failureCallback) Dicho esto, recomiendo enfáticamente mirar cacheman-redis y también familiarizarse con las funciones y promesas async/await. Cada uno simplificará su código en gran medida.
redisClient.connect(); realmente no espera antes de que la conexión tenga éxito. Si está ejecutando los comandos antes de que tenga una conexión exitosa, no funcionará. Debe esperar antes de que se conecte y luego sea seguro ejecutar los comandos de Redis.
Puede eliminar redisClient.connect(); desde su archivo redis.js y utilícelo en index.js donde lo conecte.
const redisClient = require('../db/redis'); (async () => { await redisClient.connect(); // Redis is connected and do your stuff below })();Además, le recomiendo que conecte Redis al principio y, cuando tenga éxito, inicie el servidor.