diff --git a/index.js b/index.js index e62782b..0797f32 100644 --- a/index.js +++ b/index.js @@ -30,13 +30,32 @@ function Cache () { expire: time + Date.now() }; - if (!isNaN(record.expire)) { + var extendedTimeout = function(expiresMs) { + // Max time that setTimeOut can handle (in milliseconds) + var maxTimeoutMs = 2147483647; + // If the time passed in to extendedTimeout is too large for setTimeout, the + // maxTimeoutMs has to be used instead. + var timeoutMs = (expiresMs > maxTimeoutMs) ? maxTimeoutMs : expiresMs; + + record.timeout = setTimeout(function() { - _del(key); - if (timeoutCallback) { - timeoutCallback(key, value); + // Calculates how much time is left till the cached data expires + var timeLeft = expiresMs - timeoutMs; + + // When timeLeft is <= 0, then the cached data has expired + if (timeLeft <= 0) { + _del(key); + if (timeoutCallback) { + timeoutCallback(key, value); + } + } else { + extendedTimeout(timeLeft); } - }.bind(this), time); + }.bind(this), timeoutMs); + }; + + if (!isNaN(record.expire)) { + extendedTimeout(time); } _cache[key] = record; diff --git a/test.js b/test.js index af0ee5a..5b95860 100644 --- a/test.js +++ b/test.js @@ -85,6 +85,17 @@ describe('node-cache', function() { expect(spy).to.have.been.calledOnce.and.calledWith('key', 'value'); }); + it('should cause the timeout callback to fire once 30 days later', function() { + var spy = sinon.spy(); + var thirtyDays = 2592000000; + var timeoutMax = 2147483648; + cache.put('key', 'value', thirtyDays, spy); + clock.tick(timeoutMax); + expect(spy).to.not.have.been.called; + clock.tick(thirtyDays-timeoutMax); + expect(spy).to.have.been.calledOnce.and.calledWith('key', 'value') + }); + it('should override the timeout callback on a new put() with a different timeout callback', function() { var spy1 = sinon.spy(); var spy2 = sinon.spy();