Comparing version 0.2.9 to 0.2.10
@@ -9,3 +9,4 @@ module.exports = { | ||
RedisConnection: require('./lib/RedisConnection'), | ||
RedundantCacheGroup: require('./lib/RedundantCacheGroup') | ||
RedundantCacheGroup: require('./lib/RedundantCacheGroup'), | ||
RedisTimeoutError: require('./lib/RedisTimeoutError') | ||
} |
@@ -17,3 +17,4 @@ var events = require('events') | ||
mset: new metrics.Timer, | ||
del: new metrics.Timer | ||
del: new metrics.Timer, | ||
timeout: new metrics.Counter | ||
} | ||
@@ -20,0 +21,0 @@ this._accessCount = 0 |
@@ -7,3 +7,12 @@ var redis = require('redis') | ||
var ServerInfo = require('./ServerInfo') | ||
var RedisTimeoutError = require('./RedisTimeoutError') | ||
/** | ||
* Default timeout for Redis request. Notice, not the timeout for connection. | ||
* It can be override by a constructor parameter. | ||
* @const | ||
* @type {number} | ||
*/ | ||
var DEFAULT_REQ_TIMEOUT_MS = 50 | ||
/** | ||
@@ -15,7 +24,10 @@ * A connection to a Redis server. | ||
* @param {string} port The port that the redis-server listens to | ||
* @param {Object=} options Additional options for this connection. | ||
* 'requestTimeoutMs' specifies the timeout of a Redis request. | ||
* @implements {CacheInstance} | ||
*/ | ||
function RedisConnection(host, port) { | ||
function RedisConnection(host, port, options) { | ||
CacheInstance.call(this) | ||
this._reqTimeoutMs = (options && options.requestTimeoutMs) || DEFAULT_REQ_TIMEOUT_MS | ||
this._isAvailable = false | ||
@@ -39,5 +51,5 @@ this._client = null | ||
var deferred = Q.defer() | ||
this._client.setex(key, Math.floor(maxAgeMs / 1000), val, deferred.makeNodeResolver()) | ||
this._client.setex(key, Math.floor(maxAgeMs / 1000), val, | ||
this._makeNodeResolverWithTimeout(deferred, 'Redis [set] key: ' + key)) | ||
return deferred.promise | ||
.fail(warnOnError) | ||
.then(this.updateStats('set')) | ||
@@ -48,2 +60,4 @@ } | ||
RedisConnection.prototype.mset = function (items, maxAgeMs) { | ||
if (!items || !items.length) return Q.resolve() | ||
var deferred = Q.defer() | ||
@@ -59,6 +73,7 @@ var msetCommand = ["MSET"] | ||
} | ||
this._client.multi(commands).exec(deferred.makeNodeResolver()) | ||
this._client.multi(commands).exec( | ||
this._makeNodeResolverWithTimeout(deferred, | ||
'Redis [mset] key.0: ' + items[0].key + ' key.length: ' + items.length)) | ||
return deferred.promise | ||
.fail(warnOnError) | ||
.then(this.updateStats('mset')) | ||
@@ -70,5 +85,5 @@ } | ||
var deferred = Q.defer() | ||
this._client.del(key, deferred.makeNodeResolver()) | ||
this._client.del(key, | ||
this._makeNodeResolverWithTimeout(deferred, 'Redis [del] key: ' + key)) | ||
return deferred.promise | ||
.fail(warnOnError) | ||
.then(this.updateStats('del')) | ||
@@ -89,3 +104,5 @@ } | ||
var deferred = Q.defer() | ||
this._client.mget(keys, deferred.makeNodeResolver()) | ||
this._client.mget(keys, | ||
this._makeNodeResolverWithTimeout(deferred, | ||
'Redis [mget] key.0: ' + keys[0] + ' key.length: ' + keys.length)) | ||
return deferred.promise | ||
@@ -110,3 +127,3 @@ .then(function (vals) { | ||
var deferred = Q.defer() | ||
this._client.info(deferred.makeNodeResolver()) | ||
this._client.info(this._makeNodeResolverWithTimeout(deferred, 'Redis [info]')) | ||
return deferred.promise | ||
@@ -179,11 +196,28 @@ .then(function (infoCmdOutput) { | ||
/** | ||
* Warn when an error occurs but continue | ||
* A helper that returns a node-style callback function with a specified timeout. | ||
* | ||
* @param {Error} e the error | ||
* @return {boolean} true | ||
* @param {Promise} deferred A deferred promise. | ||
* @param {string} timeoutMsg The message to throw if timeout happens. | ||
* @return {function(Object, Object)} A node-style callback function. | ||
*/ | ||
function warnOnError(e) { | ||
// if the cache set failed for some reason, warn but continue | ||
console.warn(e) | ||
return true | ||
RedisConnection.prototype._makeNodeResolverWithTimeout = function (deferred, timeoutMsg) { | ||
// Indicates if this request has already timeout | ||
var isTimeout = false | ||
var timeoutCounter = this._stats.timeout | ||
var timeout = setTimeout(function() { | ||
deferred.reject(new RedisTimeoutError(timeoutMsg)) | ||
isTimeout = true | ||
timeoutCounter.inc() | ||
}, this._reqTimeoutMs) | ||
return function(err, data) { | ||
if (!isTimeout) { | ||
clearTimeout(timeout) | ||
if (err) deferred.reject(err) | ||
else deferred.resolve(data) | ||
} | ||
//TODO(Xiao): even if it's timeout, we may want to log the error message | ||
//if this request finally goes through but fails. | ||
} | ||
} | ||
@@ -190,0 +224,0 @@ |
{ | ||
"name": "zcache", | ||
"description": "AWS zone-aware multi-layer cache", | ||
"version": "0.2.9", | ||
"version": "0.2.10", | ||
"homepage": "https://github.com/Obvious/zcache", | ||
@@ -6,0 +6,0 @@ "authors": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
96671
25
2290