Created
January 20, 2017 09:51
-
-
Save afoninsky/c86fe3929c6ef8db74a5ee00d936c07b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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