You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.1 KiB

module.exports = AsyncCache
var LRU = require('lru-cache')
function AsyncCache (opt) {
if (!opt || typeof opt !== 'object') {
throw new Error('options must be an object')
}
if (!opt.load) {
throw new Error('load function is required')
}
if (!(this instanceof AsyncCache)) {
return new AsyncCache(opt)
}
this._opt = opt
this._cache = new LRU(opt)
this._load = opt.load
this._loading = {}
this._stales = {}
this._allowStale = opt.stale
}
Object.defineProperty(AsyncCache.prototype, 'itemCount', {
get: function () {
return this._cache.itemCount
},
enumerable: true,
configurable: true
})
AsyncCache.prototype.get = function (key, cb) {
var stale = this._stales[key]
if (this._allowStale && stale !== undefined) {
return process.nextTick(function () {
cb(null, stale)
})
}
if (this._loading[key]) {
return this._loading[key].push(cb)
}
var has = this._cache.has(key)
var cached = this._cache.get(key)
if (has && undefined !== cached) {
return process.nextTick(function () {
cb(null, cached)
})
}
if (undefined !== cached && this._allowStale && !has) {
this._stales[key] = cached
process.nextTick(function () {
cb(null, cached)
})
} else {
this._loading[key] = [ cb ]
}
this._load(key, function (er, res, maxAge) {
if (!er) {
this._cache.set(key, res, maxAge)
}
if (this._allowStale) {
delete this._stales[key]
}
var cbs = this._loading[key]
if (!cbs) {
return
}
delete this._loading[key]
cbs.forEach(function (cb) {
cb(er, res)
})
}.bind(this))
}
AsyncCache.prototype.keys = function () {
return this._cache.keys()
}
AsyncCache.prototype.set = function (key, val, maxAge) {
return this._cache.set(key, val, maxAge)
}
AsyncCache.prototype.reset = function () {
return this._cache.reset()
}
AsyncCache.prototype.has = function (key) {
return this._cache.has(key)
}
AsyncCache.prototype.del = function (key) {
return this._cache.del(key)
}
AsyncCache.prototype.peek = function (key) {
return this._cache.peek(key)
}