Browse Source

refactoring, cleanup, test for error handling in getAndPassUp()

feature/specify-what-to-cache
Bryan Donovan 10 years ago
parent
commit
444d43d934
  1. 66
      lib/multi_caching.js
  2. 48
      test/multi_caching.unit.js

66
lib/multi_caching.js

@ -23,7 +23,7 @@ var multiCaching = function(caches) {
async.eachSeries(caches, function(cache, next) {
var callback = function(err, result) {
if (err) {
return cb(err);
return next(err);
}
if (result) {
// break out of async loop.
@ -31,8 +31,9 @@ var multiCaching = function(caches) {
}
i += 1;
next(err);
next();
};
if (typeof options === 'object') {
cache.store.get(key, options, callback);
} else {
@ -43,10 +44,10 @@ var multiCaching = function(caches) {
function setInMultipleCaches(caches, opts, cb) {
async.each(caches, function(cache, next) {
if (typeof opts.options !== 'object') {
cache.store.set(opts.key, opts.value, opts.ttl, next);
} else {
if (typeof opts.options === 'object') {
cache.store.set(opts.key, opts.value, opts.options, next);
} else {
cache.store.set(opts.key, opts.value, opts.ttl, next);
}
}, cb);
}
@ -96,6 +97,20 @@ var multiCaching = function(caches) {
options = undefined;
}
function getOptsForSet(result) {
var opts = {
key: key,
value: result,
options: options
};
if (typeof options !== 'object') {
opts.ttl = options;
}
return opts;
}
var hasKey = callbackFiller.has(key);
callbackFiller.add(key, {cb: cb, domain: process.domain});
if (hasKey) { return; }
@ -105,45 +120,26 @@ var multiCaching = function(caches) {
return callbackFiller.fill(key, err);
} else if (result) {
var cachesToUpdate = caches.slice(0, index);
var opts = {
key: key,
value: result,
options: options
};
if (typeof options !== 'object') {
opts.ttl = options;
}
var opts = getOptsForSet(result);
setInMultipleCaches(cachesToUpdate, opts, function(err) {
callbackFiller.fill(key, err, result);
});
} else {
domain
.create()
.on('error', function(err) {
callbackFiller.fill(key, err);
})
.bind(work)(function(err, data) {
.create()
.on('error', function(err) {
callbackFiller.fill(key, err);
})
.bind(work)(function(err, data) {
if (err) {
callbackFiller.fill(key, err);
return;
}
var opts = {
key: key,
value: data,
options: options
};
if (typeof options !== 'object') {
opts.ttl = options;
return callbackFiller.fill(key, err);
}
var opts = getOptsForSet(data);
setInMultipleCaches(caches, opts, function(err) {
if (err) {
callbackFiller.fill(key, err);
} else {
callbackFiller.fill(key, null, data);
}
callbackFiller.fill(key, err, data);
});
});
}

48
test/multi_caching.unit.js

@ -47,7 +47,9 @@ describe("multiCaching", function() {
it("lets us set data in all caches", function(done) {
multiCache.set(key, value, ttl, function(err) {
checkErr(err);
memoryCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache2.get(key, function(err, result) {
@ -68,8 +70,11 @@ describe("multiCaching", function() {
multiCache.set(key, value, ttl);
setTimeout(function() {
multiCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache2.get(key, function(err, result) {
@ -91,8 +96,11 @@ describe("multiCaching", function() {
multiCache.set(key, value);
setTimeout(function() {
multiCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache.get(key, function(err, result) {
checkErr(err);
assert.equal(result, value);
memoryCache2.get(key, function(err, result) {
@ -159,6 +167,7 @@ describe("multiCaching", function() {
setTimeout(function() {
memoryCache.get(key, function(err, result) {
checkErr(err);
assert.ok(!result);
memoryCache2.get(key, function(err, result) {
@ -263,6 +272,32 @@ describe("multiCaching", function() {
});
});
});
context("when a cache store calls back with an error", function() {
var fakeError;
var memoryStoreStub;
beforeEach(function() {
memoryStoreStub = memoryStore.create({ttl: ttl});
sinon.stub(memoryStore, 'create').returns(memoryStoreStub);
memoryCache = caching({store: 'memory', ttl: ttl});
multiCache = multiCaching([memoryCache]);
fakeError = new Error(support.random.string());
sinon.stub(memoryStoreStub, 'get').yields(fakeError);
});
afterEach(function() {
memoryStore.create.restore();
});
it("bubbles up errors from caches", function(done) {
multiCache.getAndPassUp(key, function(err) {
assert.ok(memoryStoreStub.get.called);
assert.equal(err, fakeError);
done();
});
});
});
});
});
@ -281,7 +316,7 @@ describe("multiCaching", function() {
memoryCache3.store.set.restore();
});
it('when a ttl is passed in', function(done) {
it('when a ttl number is passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, ttl, function(err, widget) {
@ -292,6 +327,17 @@ describe("multiCaching", function() {
});
});
it('when a ttl option is passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);
}, {ttl: ttl}, function(err, widget) {
checkErr(err);
assert.deepEqual(widget, {name: name});
sinon.assert.calledWith(memoryCache3.store.set, key, {name: name}, {ttl: ttl});
done();
});
});
it('when a ttl is not passed in', function(done) {
multiCache.wrap(key, function(cb) {
methods.getWidget(name, cb);

Loading…
Cancel
Save