Permalink
Browse files

Allow background fetches of stale data

Fix #2
  • Loading branch information...
1 parent e4a496a commit 0ed261bc0159fad2c1dff6f2f316b6cdd3a5fe06 @isaacs committed Oct 19, 2012
Showing with 49 additions and 15 deletions.
  1. +19 −14 ac.js
  2. +1 −1 package.json
  3. +29 −0 test/basic.js
View
33 ac.js
@@ -3,42 +3,47 @@ module.exports = AsyncCache;
var LRU = require('lru-cache');
function AsyncCache(opt) {
- if (!opt || typeof opt !== 'object') {
+ if (!opt || typeof opt !== 'object')
throw new Error('options must be an object');
- }
- if (!opt.load) {
+ if (!opt.load)
throw new Error('load function is required');
- }
- if (!(this instanceof AsyncCache)) {
+ if (!(this instanceof AsyncCache))
return new AsyncCache(opt);
- }
this._opt = opt;
this._cache = new LRU(opt);
this._load = opt.load;
this._loading = {};
+ this._allowStale = opt.stale;
}
AsyncCache.prototype.get = function(key, cb) {
- if (this._loading[key]) {
- this._loading[key].push(cb);
- return;
- }
+ if (this._loading[key])
+ return this._loading[key].push(cb);
+ var has = this._cache.has(key);
var cached = this._cache.get(key);
- if (cached) {
+ if (has && void 0 !== cached)
return process.nextTick(function() {
cb(null, cached);
});
- }
- this._loading[key] = [ cb ];
+ if (void 0 !== cached && this._allowStale && !has)
+ process.nextTick(function() {
+ cb(null, cached);
+ });
+ else
+ this._loading[key] = [ cb ];
+
this._load(key, function(er, res) {
- if (!er) this._cache.set(key, res);
+ if (!er)
+ this._cache.set(key, res);
var cbs = this._loading[key];
+ if (!cbs)
+ return;
delete this._loading[key];
cbs.forEach(function (cb) {
View
@@ -7,7 +7,7 @@
"test": "test"
},
"dependencies": {
- "lru-cache": "~2.0.0"
+ "lru-cache": "~2.1.0"
},
"devDependencies": {
"tap": "~0.3.0"
View
@@ -62,3 +62,32 @@ test('basic', function(t) {
});
}
});
+
+test('allow stale', function(t) {
+ var v = 0;
+ var ac = new AC({
+ max: 1,
+ load: function(key, cb) {
+ setTimeout(function() {
+ cb(null, v++);
+ }, 100);
+ },
+ maxAge: 10,
+ stale: true
+ });
+
+ ac.get('foo', function(er, val) {
+ console.error('result', er, val);
+ t.equal(val, 0);
+ var start = Date.now();
+ setTimeout(function() {
+ ac.get('foo', function(er, val) {
+ console.error('result2', er, val);
+ var end = Date.now();
+ t.equal(val, 0);
+ t.ok(end - start < 50, 'should be stale');
+ t.end();
+ });
+ }, 15);
+ });
+});

0 comments on commit 0ed261b

Please sign in to comment.