Skip to content

Instantly share code, notes, and snippets.

@junibrosas
Forked from StarpTech/redis-cache-service.js
Created April 22, 2019 11:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save junibrosas/d703d106a03d772f203ff1a3701da71b to your computer and use it in GitHub Desktop.
Save junibrosas/d703d106a03d772f203ff1a3701da71b to your computer and use it in GitHub Desktop.
Simple Redis Cache Client for Node.js
'use strict';
const assert = require('assert');
/**
* The redis client is https://github.com/luin/ioredis
*/
/*
const redisClient = new Redis({
host: process.env.LCA_REDIS_HOST,
port: process.env.LCA_REDIS_PORT
});
const redisCacheService = new CacheService(redisClient);
const cache = redisCacheService.child('products');
const name = `key`;
await cache.exists(name);
await cache.get(name);
await cache.set(name, html);
await cache.remove(name);
await cache.removeAll();
*/
class RedisCacheService {
constructor(redisClient) {
this.client = redisClient;
}
/**
* Creates a new child cache
* @param {*} prefix
*/
child(prefix, isJson = false) {
const self = this;
return {
/**
* Remove all entrys from the cache with the root prefix
*/
removeAll() {
assert(prefix, 'Cache prefix is required');
let localKeys = [];
return new Promise((resolve, reject) => {
const stream = self.client.scanStream({
// only returns keys following the pattern of "key*"
match: `${prefix}*`,
// returns approximately 100 elements per call
count: 100
});
let pipeline = self.client.pipeline();
stream.on('data', resultKeys => {
// eslint-disable-next-line no-plusplus
for (let i = 0; i < resultKeys.length; i++) {
localKeys.push(resultKeys[i]);
pipeline.del(resultKeys[i]);
}
if (localKeys.length > 100) {
pipeline.exec();
localKeys = [];
pipeline = self.client.pipeline();
}
});
stream.on('error', err => reject(err));
stream.on('end', () => {
// fin batch
pipeline.exec(() => resolve(true));
});
});
},
/**
* Return the value behind the key
* @param {string} name
*/
async get(name) {
assert(name, 'Cache item name is required');
const data = await self.client.get(`${prefix}/${name}`);
return isJson ? JSON.parse(data) : data;
},
/**
* Store the value with a default expiration time of 300 seconds (5min)
* @param {string} name
* @param {any} value
*/
set(name, value, expiredInSec = 300) {
assert(name, 'Cache item name is required');
assert(value, 'Cache item value is required');
return self.client.setex(`${prefix}/${name}`, expiredInSec, isJson ? JSON.stringify(value) : value);
},
/**
* Returns the remaining expiration time of the item
* @param {string} name
*/
getExpiration(name) {
assert(name, 'Cache item name is required');
return self.client.ttl(`${prefix}/${name}`);
},
/**
* Check if a key exists
* @param {string} name
*/
exists(name) {
assert(name, 'Cache item name is required');
return self.client.exists(`${prefix}/${name}`);
},
/**
* Remove the item from the store
* @param {string} name
*/
remove(name) {
assert(name, 'Cache item name is required');
return self.client.unlink([`${prefix}/${name}`]);
}
};
}
}
module.exports = RedisCacheService;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment