Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * 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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement