From dab8b072fa0844eb189f60cbaf97008764296fa7 Mon Sep 17 00:00:00 2001 From: vmarchaud Date: Wed, 21 Jun 2017 13:33:47 +0200 Subject: [PATCH] (interactor) implement a 30 ttl for cached file in ram (#2763) --- lib/Interactor/PushInteractor.js | 7 ++-- lib/Interactor/Utility.js | 59 ++++++++++++++++++++++++-------- test/interface/cache.mocha.js | 25 ++++++++++++++ 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/lib/Interactor/PushInteractor.js b/lib/Interactor/PushInteractor.js index 0e0cfd8d..0f67ed21 100644 --- a/lib/Interactor/PushInteractor.js +++ b/lib/Interactor/PushInteractor.js @@ -129,9 +129,10 @@ var PushInteractor = module.exports = { debug('Error while trying to get file from FS : %s', err.message || err) return undefined; } - } - }) - self.stackParser = new InteractorUtility.StackTraceParser({ cache: self.cache, context: cst.CONTEXT_ON_ERROR}); + }, + ttl: 60 * 30 + }); + self.stackParser = new InteractorUtility.StackTraceParser({ cache: self.cache, context: cst.CONTEXT_ON_ERROR }); self.aggregator = new Aggregator(self); self.aggregator.init(); }, diff --git a/lib/Interactor/Utility.js b/lib/Interactor/Utility.js index 951c33b0..25014057 100644 --- a/lib/Interactor/Utility.js +++ b/lib/Interactor/Utility.js @@ -32,23 +32,49 @@ EWMA.prototype.rate = function (timeUnit) { return (this._rate || 0) * timeUnit } +var moment = require('moment'); + /** * Simple cache implementation * * @param {Object} opts cache options + * @param {Integer} opts.ttl time to live of all the keys * @param {Function} opts.miss function called when a key isn't found in the cache */ function Cache (opts) { - this._cache = {} - this._miss = opts.miss + this._cache = {}; + this._miss = opts.miss; + this._ttl_time = opts.ttl; + this._ttl = {}; + + if (opts.ttl) { + setInterval(this._worker.bind(this), 1000); + } } +/** + * Task running to check TTL and potentially remove older key + */ +Cache.prototype._worker = function () { + var keys = Object.keys(this._ttl); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = this._ttl[key]; + if (moment().isAfter(value)) { + delete this._cache[key]; + delete this._ttl[key]; + } + } +}; + /** * Empty the cache */ Cache.prototype.reset = function () { this._cache = null; this._cache = {}; + this._ttl = null; + this._ttl = {}; }; /** @@ -57,17 +83,17 @@ Cache.prototype.reset = function () { * @param {String} key */ Cache.prototype.get = function (key) { - if (!key) return null - var value = this._cache[key] - if (value) return value + if (!key) return null; + var value = this._cache[key]; + if (value) return value; - value = this._miss(key) + value = this._miss(key); - if (value) - this.set(key, value) - - return value -} + if (value) { + this.set(key, value); + } + return value; +}; /** * Set a value in the cache @@ -76,10 +102,13 @@ Cache.prototype.get = function (key) { * @param {Mixed} value */ Cache.prototype.set = function (key, value) { - if (!key || !value) return false - this._cache[key] = value - return true -} + if (!key || !value) return false; + this._cache[key] = value; + if (this._ttl_time) { + this._ttl[key] = moment().add(this._ttl_time, 'seconds'); + } + return true; +}; /** * StackTraceParser is used to parse callsite from stacktrace diff --git a/test/interface/cache.mocha.js b/test/interface/cache.mocha.js index 7467ae61..bfcd9d8c 100644 --- a/test/interface/cache.mocha.js +++ b/test/interface/cache.mocha.js @@ -58,4 +58,29 @@ describe('Cache Utility', function() { should(cache.get('toto')).be.null(); }); + it('should instanciate context cache with ttl', function() { + cache = new Utility.Cache({ + miss: function (key) { + try { + var content = fs.readFileSync(path.resolve(key)); + return content.toString().split(/\r?\n/); + } catch (err) { + return null; + } + }, + ttl: 1 + }); + }); + + it('should add a key', function () { + should(cache.set('toto', 'yeslife')).be.true(); + }); + + it('should wait one second to see the key disapear', function (done) { + setTimeout(function () { + should(cache.get('toto')).be.null(); + done(); + }, 1000); + }); + });