regard
Version:
Sugar-interface to access multiple data sources.
109 lines (84 loc) • 2.65 kB
JavaScript
var _ = require('lodash'),
Cache = require('lru-cache'),
CachedPromise = require('cached-promise'),
Q = require('q');
exports = module.exports = RequestsManager;
exports.CACHE_MAX = 100;
exports.CACHE_MAXAGE = 1000 * 30;
function RequestsManager() {
if (!(this instanceof RequestsManager)) {
return new RequestsManager();
}
this.data = new Cache({
max: exports.CACHE_MAX,
maxAge: exports.CACHE_MAXAGE
});
this.promises = new CachedPromise({
max: exports.CACHE_MAX,
maxAge: exports.CACHE_MAXAGE,
load: _.bind(this.prepareCache, this)
});
}
RequestsManager.prototype.add = function (item) {
this.data.set(item.key, item);
return this;
};
RequestsManager.prototype.get = function (key) {
return this.data.get(key);
};
RequestsManager.prototype.has = function (key) {
return this.data.has(key);
};
RequestsManager.prototype.prepare = function (request) {
if (request.context.$cache) {
return this.promises.get(request.key);
}
var processing = Q.defer();
processRequest.call(this, request, processing.resolve, processing.reject);
return processing.promise;
};
RequestsManager.prototype.prepareCache = function(key, resolve, reject) {
var hash = key.key,
request = this.get(hash);
processRequest.call(this, request, resolve, reject);
};
function processRequest(request, resolve, reject) {
var endpoint = request.endpoint,
connector = endpoint.connector,
handler = connector.handlers.get(request.handler);
var after = [];
after.push(handler.after);
after.push(resolveProcess(endpoint, 'afterProcess'));
after = _.compact(after);
after = after.length > 0 ? _.flow.apply(_, after) : undefined;
var before = [];
before.push(resolveProcess(endpoint, 'beforeProcess'));
before.push(handler.before);
before = _.compact(before);
before = before.length > 0 ? _.flow.apply(_, before) : undefined;
var beforeProcess = function stage0(req) {
if (_.isFunction(before)) {
req = _.partial(before, req).apply(connector, req.args);
}
return req;
};
var mainProcess = function stage1(req) {
return Q.Promise(_.bind(handler.process, connector, req));
};
var afterProcess = function stage2(res) {
if (_.isFunction(after)) {
res = after.call(connector, res);
}
return res;
};
Q.resolve(beforeProcess(request))
.then(mainProcess, reject)
.then(afterProcess, reject)
.then(resolve, reject);
}
function resolveProcess(endpoint, name) {
var stack = [];
endpoint.walk(stack, name);
stack = _(stack).compact().value().pop();
return stack;
}