Skip to content

Instantly share code, notes, and snippets.

@afoninsky
Created January 20, 2017 09:51
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 afoninsky/c86fe3929c6ef8db74a5ee00d936c07b to your computer and use it in GitHub Desktop.
Save afoninsky/c86fe3929c6ef8db74a5ee00d936c07b to your computer and use it in GitHub Desktop.
/**
* Create method which can be throttled in different ways using redis cache
*/
'use strict'
// global-level options
const defaultConfig = {
redis: null, // redis instance (required)
key: 'cache', // global redis key
ttl: null // global ttl value
}
// .wrap method options
const defaultWrapConfig = {
hash: null, // local redis key
ttl: null // cache ttl
}
class Cache {
constructor(cfg, redis) {
this.cfg = Object.assign({}, defaultConfig, cfg)
this.redis = redis || this.cfg.redis
if (!this.redis) {
throw new Error('please provide cfg.redis instance')
}
}
flush(hash) {
const redisKey = this.redisKey(hash)
return this.redis.del(redisKey)
}
redisKey(hash) {
return `${hash}::${this.cfg.key}`
}
/**
* Return wrapped method which execute payload and cache result
*/
wrap(payload, opt) {
const cfg = Object.assign({}, defaultWrapConfig, opt)
const ttl = cfg.ttl || this.cfg.ttl
if (!cfg.hash) {
throw new Error('please specify wrap.cfg.hash')
}
const redisKey = this.redisKey(cfg.hash)
const redis = this.redis
return function wrappedMethod() {
const payloadArgs = arguments
let isCacheExists = false
return Promise.resolve().then(() => {
// test existing cache
return redis.get(redisKey).then(res => {
isCacheExists = (res !== null)
return JSON.parse(res)
})
}).then(data => {
// execute payload
if (isCacheExists) {
return data
}
return payload.apply(null, payloadArgs).then(res => {
const cacheArgs = [redisKey, JSON.stringify(res)]
if (ttl) {
cacheArgs.push('PX', ttl)
}
return redis.set.apply(redis, cacheArgs).then(() => res)
})
})
}
}
}
module.exports = Cache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment