Skip to content

Instantly share code, notes, and snippets.

@zz85
Last active September 23, 2015 05:28
Show Gist options
  • Save zz85/5089398aed0d496de32a to your computer and use it in GitHub Desktop.
Save zz85/5089398aed0d496de32a to your computer and use it in GitHub Desktop.
Request + LRU Cache
var request = require('request');
var LRU = require('lru-cache');
/*
Request + LRU Cache
- request_cache(target, callback() {})
*/
var cache = LRU({
max: 10000,
maxAge: 10 * 60 * 1000
});
var
KEY_PREFIX = 'rcache:',
STATE_PENDING = 'pending',
STATE_DONE = 'done',
REQUEST_TIMEOUT = 4000,
PENDING_REQUEST_TIMEOUT = 8000,
REQUEST_EXPIRY = 12000;
function RCacheItem(callback) {
this.state = STATE_PENDING;
this.callbacks = [callback];
this.res = null;
}
function Result(error, response, body) {
this.error = error;
this.response = response;
this.body = body;
}
function request_cache(uri, callback) {
var key = KEY_PREFIX + uri;
var hit = cache.get(key);
if (hit) {
if (hit.state === STATE_PENDING) {
return hit.callbacks.push(callback);
}
else if (hit.state === STATE_DONE) {
var res = hit.res;
callback(res.error, res.response, res.body);
}
return;
}
var item = new RCacheItem(callback);
cache.set(key, item, PENDING_REQUEST_TIMEOUT);
var target = {
uri: uri,
timeout: REQUEST_TIMEOUT
};
request(target, handleResponse);
function handleResponse(error, response, body) {
// TODO handle retries here
handleDone(error, response, body);
}
function handleDone(error, response, body) {
item.res = new Result(error, response, body);
item.state = STATE_DONE;
cache.set(key, item, REQUEST_EXPIRY);
items.callbacks.forEach(function(callback) {
callback(error, response, body);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment