diff --git a/README.md b/README.md index 0a3efbc5..9be5f054 100644 --- a/README.md +++ b/README.md @@ -483,6 +483,7 @@ REDIS_PASS REDIS_HOST REDIS_PORT REDIS_DATABASE +REDIS_TIMEOUT_MS ``` **_Please config your config/app.js_** diff --git a/example/usingRedis/.env b/example/usingRedis/.env index db64b6be..890e231f 100644 --- a/example/usingRedis/.env +++ b/example/usingRedis/.env @@ -3,3 +3,4 @@ REDIS_HOST=localhost REDIS_PORT=6379 REDIS_DATABASE=nodejs-framework-redis-example +REDIS_TIMEOUT_MS=4000 \ No newline at end of file diff --git a/lib/config/redis.js b/lib/config/redis.js index 1a4f00b6..699f3398 100644 --- a/lib/config/redis.js +++ b/lib/config/redis.js @@ -4,6 +4,6 @@ module.exports = { port: process.env.REDIS_PORT, database: process.env.REDIS_DATABASE, user: process.env.REDIS_USER, - pass: process.env.REDIS_PASS - + pass: process.env.REDIS_PASS, + timeoutMs: process.env.REDIS_TIMEOUT_MS, } diff --git a/lib/plugins/redis/lib/Redis.js b/lib/plugins/redis/lib/Redis.js index 05e2dd11..94e7cc7d 100644 --- a/lib/plugins/redis/lib/Redis.js +++ b/lib/plugins/redis/lib/Redis.js @@ -1,3 +1,5 @@ +const Promise = require('bluebird'); + let _sharedRedis = null let _redisLib @@ -9,8 +11,42 @@ class Redis { init(config) { this.redis = require('redis') - Promise.promisifyAll(this.redis.RedisClient.prototype) - Promise.promisifyAll(this.redis.Multi.prototype) + const customPromisifier = (originalMethod) => { + return function (...args) { + return new Promise((resolve, reject) => { + let timeout; + // for backward compatibility, only provide timeout mechanism if config.timeoutMs is set + if (config.timeoutMs) { + timeout = setTimeout(() => { + reject( + new Error(`Redis operation "${originalMethod.name}" timed out`) + ); + }, config.timeoutMs); + } + + const callback = (err, result) => { + if (timeout) { + clearTimeout(timeout); + } + if (err) { + return reject(err); + } + resolve(result); + }; + + args.push(callback); + + originalMethod.apply(this, args); + }); + }; + }; + + Promise.promisifyAll(this.redis.RedisClient.prototype, { + promisifier: customPromisifier, + }); + Promise.promisifyAll(this.redis.Multi.prototype, { + promisifier: customPromisifier, + }); this.host = config.host this.port = config.port @@ -46,69 +82,32 @@ class Redis { } get(id) { + return this.client.getAsync(id); + } - return new Promise((resolve, reject) => { - - this.client.get(id, function(err, reply) { - - if (err) return reject(err) - - return resolve(reply) - - }) - - }) - + mget(ids) { + return this.client.mgetAsync(ids); } set(id, data, option, duration) { - - return new Promise((resolve, reject) => { - - this.client.set(id, data, option, duration, function(err, reply) { - - if (err) return reject(err) - - return resolve(reply) - - }) - - }) - + return this.client.setAsync(id, data, option, duration); } del(id) { - - return new Promise((resolve, reject) => { - - this.client.del(id, function(err, reply) { - - if (err) return reject(err) - - return resolve(reply) - - }) - - }) - + return this.client.delAsync(id); } - disconnect() { - + disconnect() { if (!this.client) return this this.client.quit() return this - } flushdb() { - - return this.client.flushdb() - + return this.client.flushdbAsync(); } - } -module.exports = Redis +module.exports = Redis \ No newline at end of file