diff --git a/lib/connection.js b/lib/connection.js index c055944..c024cc4 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -41,6 +41,8 @@ function IssueLog (args) { this.totalReconnectsAttempted = 0; this.totalReconnectsSuccess = 0; + this.timers = []; + Utils.merge(this, args); EventEmitter.call(this); } @@ -56,22 +58,26 @@ issues.log = function log (message) { // All failures must occur within `failuresTimeout` ms from the initial // failure in order for node to be disconnected or removed. - if (this.failures && this.failures == this.config.failures) - this.failuresResetId = setTimeout(issue.failuresReset.bind(issue), this.failuresTimeout); + if (this.failures && this.failures == this.config.failures) { + this.failuresResetId = issue.setTimeout( + issue.failuresReset.bind(issue), + this.failuresTimeout + ); + } if (this.failures && !this.locked) { this.locked = true; - setTimeout(issue.attemptRetry.bind(issue), this.retry); + issue.setTimeout(issue.attemptRetry.bind(issue), this.retry); return this.emit('issue', this.details); } - if (this.failuresResetId) clearTimeout(this.failuresResetId); + if (this.failuresResetId) this.clearTimeout(this.failuresResetId); if (this.remove) return this.emit('remove', this.details); if (!this.isScheduledToReconnect) { this.isScheduledToReconnect = true; - setTimeout(issue.attemptReconnect.bind(issue), this.reconnect); + issue.setTimeout(issue.attemptReconnect.bind(issue), this.reconnect); } }; @@ -119,7 +125,10 @@ issues.attemptReconnect = function attemptReconnect () { // still no access to the server if (err) { issue.messages.push(err.message || 'No message specified'); - return setTimeout(issue.attemptReconnect.bind(issue), issue.reconnect); + return issue.setTimeout( + issue.attemptReconnect.bind(issue), + issue.reconnect + ); } issue.emit('reconnected', issue.details); @@ -133,3 +142,36 @@ issues.attemptReconnect = function attemptReconnect () { Utils.merge(issue, JSON.parse(JSON.stringify(issue.config))); }); }; + + +issues.setTimeout = function IssueLog_setTimeout (fn, ms) { + var issue = this; + + var timer = setTimeout(function setTimeoutWrappedFn () { + issue.clearTimeout(timer); + + fn(); + }, ms); + + this.timers.push(timer); + + return timer; +}; + +issues.clearTimeout = function IssueLog_clearTimeout (timer) { + clearTimeout(timer); + + var index = this.timers.indexOf(timer); + + if (index >= 0) { + this.timers.splice(index, 1); + } +}; + +issues.clearTimers = function clearTimers () { + for (let i = 0; i < this.timers.length; i++) { + clearTimeout(this.timers[i]); + } + + this.timers = []; +}; diff --git a/lib/memcached.js b/lib/memcached.js index 9742a1d..8f79c6b 100644 --- a/lib/memcached.js +++ b/lib/memcached.js @@ -437,6 +437,10 @@ Client.config = { Object.keys(this.connections).forEach(function closeConnection(key) { memcached.connections[key].free(0); }); + + Object.keys(this.issues).forEach(function issueClearTimers(issue) { + memcached.issues[issue].clearTimers(); + }); }; // These do not need to be publicly available as it's one of the most important