diff --git a/lib/multi_caching.js b/lib/multi_caching.js index 2dc52e7..4cb4b77 100644 --- a/lib/multi_caching.js +++ b/lib/multi_caching.js @@ -31,6 +31,30 @@ var multi_caching = function (caches) { }, cb); } + /** + * Looks for an item in cache tiers. + * + * When a key is found in a lower cache, all higher levels are updated + */ + + self.get_and_pass_up = function(key, cb) { + get_from_highest_priority_cache(key, function(err, result, index) { + if (err) { + return cb(err); + } + + result = result || {}; + cb(err, result); + + if (result && index) { + var cachesToUpdate = caches.slice(0, index); + async.forEach(cachesToUpdate, function(cache, async_cb) { + cache.set(key, result, result.ttl, async_cb); + }); + } + }); + }; + /** * Wraps a function in one or more caches. * Has same API as regular caching module. diff --git a/test/multi_caching.unit.js b/test/multi_caching.unit.js index 746c951..37ba211 100644 --- a/test/multi_caching.unit.js +++ b/test/multi_caching.unit.js @@ -178,6 +178,58 @@ describe("multi_caching", function () { }); }); + describe("get_and_pass_up()", function () { + var value; + var key; + + describe("using a single cache store", function () { + beforeEach(function () { + multi_cache = multi_caching([memory_cache3]); + key = support.random.string(20); + value = support.random.string(); + }); + + it("gets data from first cache that has it", function (done) { + memory_cache3.set(key, value, ttl, function (err) { + check_err(err); + + multi_cache.get_and_pass_up(key, function (err, result) { + check_err(err); + assert.equal(result, value); + done(); + }); + }); + }); + }); + + describe("using multi cache store", function () { + beforeEach(function () { + multi_cache = multi_caching([memory_cache,memory_cache2,memory_cache3]); + key = support.random.string(20); + value = support.random.string(); + }); + + it("checks to see if higher levels have item", function (done) { + memory_cache3.set(key, value, ttl, function (err) { + check_err(err); + + multi_cache.get_and_pass_up(key, function (err, result) { + check_err(err); + assert.equal(result, value); + + process.nextTick(function() { + memory_cache.get(key, function (err, result) { + assert.equal(result, value); + check_err(err); + done(); + }); + }); + }); + }); + }); + }); + }); + describe("wrap()", function () { describe("using a single cache store", function () { beforeEach(function () {