added ttl

This commit is contained in:
javi 2011-10-21 16:33:35 +02:00
parent 87b04ce80a
commit f0b8c29b03
3 changed files with 117 additions and 4 deletions

View File

@ -4,7 +4,8 @@
// 'lru' implements a LRU cache // 'lru' implements a LRU cache
var LRUCache = require('./lru'), var LRUCache = require('./lru'),
CacheValidator = require('./cache_validator') CacheValidator = require('./cache_validator'),
TTL = require('./TTL');
var BLANK_TILE_SIZE = 334; // totally transparent tile size in bytes var BLANK_TILE_SIZE = 334; // totally transparent tile size in bytes
@ -31,7 +32,7 @@ module.exports.LRUcache = function(max_items, redis_opts) {
// implements a generic cache for tile // implements a generic cache for tile
// cache_policy should implement set and get methods and optionally getStats // cache_policy should implement set and get methods and optionally getStats
function GenericCache (cache_policy, cache_validator) { function GenericCache (cache_policy, cache_validator, ttl_timeout) {
var me = { var me = {
cache: cache_policy, cache: cache_policy,
@ -40,9 +41,16 @@ function GenericCache (cache_policy, cache_validator) {
cache_misses: 0, cache_misses: 0,
cache_not_modified: 0, cache_not_modified: 0,
current_items: 0, current_items: 0,
expired: 0,
cache_invalidated: 0, cache_invalidated: 0,
max_items: 0 max_items: 0
} };
// enable ttl
var ttl = TTL(function(key) {
me.remove(key);
me.expired++;
}, ttl_timeout || 60);
function cache_key(req) { function cache_key(req) {
return req.url; return req.url;
@ -55,6 +63,12 @@ function GenericCache (cache_policy, cache_validator) {
} }
} }
me.remove = function(key) {
ttl.remove(key);
me.cache.remove(key);
update_items(me.cache.size || 0);
}
me.beforeTileRender = function(req, res, callback) { me.beforeTileRender = function(req, res, callback) {
req.windshaft_start = new Date().getTime(); req.windshaft_start = new Date().getTime();
var key = cache_key(req); var key = cache_key(req);
@ -97,12 +111,14 @@ function GenericCache (cache_policy, cache_validator) {
me.afterTileRender = function(req, res, tile, headers, callback) { me.afterTileRender = function(req, res, tile, headers, callback) {
var timestamp = new Date().getTime(); var timestamp = new Date().getTime();
var delta = timestamp - req.windshaft_start; var delta = timestamp - req.windshaft_start;
me.cache.put(cache_key(req), { var key = cache_key(req);
me.cache.put(key, {
tile: tile, tile: tile,
headers: headers, headers: headers,
timestamp: timestamp/1000.0, timestamp: timestamp/1000.0,
render_time: delta/1000.0, render_time: delta/1000.0,
hits: 0}); hits: 0});
ttl.start(key);
update_items(me.cache.size || 0); update_items(me.cache.size || 0);
callback(null, tile, headers); callback(null, tile, headers);
} }

47
lib/cartodb/ttl.js Normal file
View File

@ -0,0 +1,47 @@
/*
==========================================================
manages timeouts
* timeout in seconds
* on_delete will be called when time expired with the key as first param
usage:
ttl = TTL(function(key) {
console.log("10 seconds expired on " + key");
}, 10);
==========================================================
*/
function TTL(on_delete, timeout) {
var me = {
timeouts: {},
on_delete: on_delete,
timeout: timeout*1000
};
me.start = function(key) {
var t = me.timeouts[key];
if (t) {
clearTimeout(t);
}
me.timeouts[key] = setTimeout(
(function(k) {
return function() {
me.on_delete(k);
};
})(key),
me.timeout);
}
me.remove = function(key) {
var t = me.timeouts[key];
if (t) {
clearTimeout(t);
delete me.timeouts[key];
}
}
return me;
}
module.exports = TTL;

View File

@ -0,0 +1,50 @@
var assert = require('assert')
, _ = require('underscore')
, TTL = require('../../../lib/cartodb/ttl')
, tests = module.exports = {};
tests['all ok'] = function() {
assert.ok(true, "ok");
}
tests['should timeout'] = function() {
var called = false;
var ttl = TTL(function() {
called = true;
}, 0.1);
ttl.start('test');
setTimeout(function() {
assert.ok(called === true, "called");
}, 200);
}
tests['should remove timeout'] = function() {
var called = false;
var ttl = TTL(function() {
called = true;
}, 0.1);
ttl.start('test');
ttl.remove('test');
setTimeout(function() {
assert.ok(called === false, "removed");
}, 200);
}
tests['should renew timeout time'] = function() {
var called = false;
var ttl = TTL(function() {
called = true;
}, 0.3);
ttl.start('test');
setTimeout(function() {
ttl.start('test');
}, 0.5);
setTimeout(function() {
assert.ok(called === false, "removed");
}, 300);
setTimeout(function() {
assert.ok(called === true, "removed");
}, 600);
}