/**
* MOST Web Framework
* A JavaScript Web Framework
* http://themost.io
*
* Copyright (c) 2014, Kyriakos Barbounakis k.barbounakis@gmail.com, Anthi Oikonomou anthioikonomou@gmail.com
*
* Released under the BSD3-Clause license
* Date: 2014-03-10
*/
/**
* @ignore
*/
var dat = require('most-data'), util = require('util');
/**
* Implements the cache for a data application.
* @class HttpCache
* @param {{ttl:number}|*} options
* @constructor
* @augments EventEmitter2
*/
function HttpCache(options) {
this.initialized = false;
options = options || {};
options.ttl = options.ttl || (20*60);
this.options = options;
}
util.inherits(HttpCache, dat.types.EventEmitter2);
/**
* Initializes data caching.
* @param {function(Error=)} callback
*/
HttpCache.prototype.init = function(callback) {
try {
if (this.initialized) {
callback();
return;
}
var NodeCache = require( "node-cache" );
this.rawCache = new NodeCache();
this.initialized = true;
callback();
}
catch (e) {
callback(e);
}
};
/**
* Removes a cached value.
* @param {string} key - A string that represents the key of the cached value
* @param {function(Error=,number=)} callback - Returns the number of deleted entries. This parameter is optional.
*/
HttpCache.prototype.remove = function(key, callback) {
var self = this;
callback = callback || function() {};
self.init(function(err) {
if (err) {
callback(err);
}
else {
self.rawCache.set(key, callback);
}
});
};
/**
* Flush all cached data.
* @param {function(Error=)} callback - This parameter is optional.
*/
HttpCache.prototype.removeAll = function(callback) {
var self = this;
callback = callback || function() {};
self.init(function(err) {
if (err) {
callback(err);
}
else {
self.rawCache.flushAll();
callback();
}
});
};
/**
* Sets a key value pair in cache.
* @param {string} key - A string that represents the key of the cached value
* @param {*} value - The value to be cached
* @param {number=} ttl - A TTL in seconds. This parameter is optional.
* @param {function(Error=,boolean=)} callback - Returns true on success. This parameter is optional.
*/
HttpCache.prototype.add = function(key, value, ttl, callback) {
var self = this;
if (typeof ttl === 'undefined')
ttl = self.options.ttl;
callback = callback || function() {};
self.init(function(err) {
if (err) {
callback(err);
}
else {
if (typeof value !== 'undefined')
self.rawCache.set(key, value, ttl, callback);
else
callback(null, false);
}
});
};
/**
* Gets data from cache or executes the defined function and adds the result to the cache with the specified key
* @param {string|*} key - A string thath represents the of the cached data
* @param {function(function(Error=,*=))} fn - A function to execute if data will not be found in cache
* @param {function(Error=,*=)} callback - A callback function that will return the result or an error, if any.
*/
HttpCache.prototype.ensure = function(key, fn, callback) {
var self = this;
callback = callback || function() {};
if (typeof fn !== 'function') {
callback(new Error('Invalid argument. Expected function.'));
return;
}
//try to get from cache
self.get(key, function(err, result) {
if (err) { callback(err); return; }
if (typeof result !== 'undefined') {
callback(null, result);
}
else {
//execute fn
fn(function(err, result) {
if (err) { callback(err); return; }
//add to cache
self.add(key, (typeof result === 'undefined') ? null: result, self.options.ttl, function() {
//and return result
callback(null, result);
});
});
}
});
};
/**
* Gets a cached value defined by the given key.
* @param {string|*} key
* @param {function(Error=,*=)} callback - A callback that returns the cached value, if any.
*/
HttpCache.prototype.get = function(key, callback) {
var self = this;
callback = callback || function() {};
if (typeof key === 'undefined' || key == null) {
callback();
}
self.init(function(err) {
if (err) {
callback(err);
}
else {
self.rawCache.get(key, function(err, value) {
if (err) {
callback(err);
}
else {
if (typeof value[key] !== 'undefined') {
callback(null, value[key]);
}
else {
callback();
}
}
});
}
});
};
if (typeof exports !== 'undefined')
{
/**
* @see HttpCache
* @constructs HttpCache
*/
module.exports = HttpCache;
}