parent
023c3d9741
commit
46190008f5
@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var _ = require('underscore');
|
||||
|
||||
function CacheStatusController(tableCache) {
|
||||
this.tableCache = tableCache;
|
||||
}
|
||||
|
||||
CacheStatusController.prototype.route = function (app) {
|
||||
app.get(global.settings.base_url + '/cachestatus', this.handleCacheStatus.bind(this));
|
||||
};
|
||||
|
||||
CacheStatusController.prototype.handleCacheStatus = function (req, res) {
|
||||
var tableCacheValues = this.tableCache.values();
|
||||
var totalExplainKeys = tableCacheValues.length;
|
||||
var totalExplainHits = _.reduce(tableCacheValues, function(memo, res) {
|
||||
return memo + res.hits;
|
||||
}, 0);
|
||||
|
||||
res.send({
|
||||
explain: {
|
||||
pid: process.pid,
|
||||
hits: totalExplainHits,
|
||||
keys : totalExplainKeys
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = CacheStatusController;
|
@ -1,44 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var QueryTables = require('cartodb-query-tables');
|
||||
|
||||
var generateMD5 = require('../utils/md5');
|
||||
|
||||
function CachedQueryTables(tableCache) {
|
||||
this.tableCache = tableCache;
|
||||
}
|
||||
|
||||
module.exports = CachedQueryTables;
|
||||
|
||||
CachedQueryTables.prototype.getAffectedTablesFromQuery = function(pg, sql, skipCache, callback) {
|
||||
var self = this;
|
||||
|
||||
var cacheKey = sqlCacheKey(pg.username(), sql);
|
||||
|
||||
var cachedResult;
|
||||
if (!skipCache) {
|
||||
cachedResult = this.tableCache.peek(cacheKey);
|
||||
}
|
||||
|
||||
if (cachedResult) {
|
||||
cachedResult.hits++;
|
||||
return callback(null, cachedResult.result);
|
||||
} else {
|
||||
QueryTables.getAffectedTablesFromQuery(pg, sql, function(err, result) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
self.tableCache.set(cacheKey, {
|
||||
result: result,
|
||||
hits: 0
|
||||
});
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function sqlCacheKey(user, sql) {
|
||||
return user + ':' + generateMD5(sql);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function generateCacheKey(database, affectedTables) {
|
||||
return database + ":" + affectedTables.join(',');
|
||||
};
|
@ -1,49 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This module provides an object with the interface of an LRU cache
|
||||
* but that actually does not store anything.
|
||||
*
|
||||
* See https://github.com/isaacs/node-lru-cache/tree/v2.5.0
|
||||
*/
|
||||
|
||||
function NoCache() {
|
||||
}
|
||||
|
||||
module.exports = NoCache;
|
||||
|
||||
NoCache.prototype.set = function (/* key, value */) {
|
||||
return true;
|
||||
};
|
||||
|
||||
NoCache.prototype.get = function (/* key */) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
NoCache.prototype.peek = function (/* key */) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
NoCache.prototype.del = function (/* key */) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
NoCache.prototype.reset = function () {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
NoCache.prototype.has = function (/* key */) {
|
||||
return false;
|
||||
};
|
||||
|
||||
NoCache.prototype.forEach = function (/* fn, thisp */) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
NoCache.prototype.keys = function () {
|
||||
return [];
|
||||
};
|
||||
|
||||
NoCache.prototype.values = function () {
|
||||
return [];
|
||||
};
|
@ -1,32 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var LRU = require('lru-cache');
|
||||
var NoCache = require('./no_cache');
|
||||
|
||||
/**
|
||||
* This module abstracts the creation of a tableCache,
|
||||
* depending on the configuration passed along
|
||||
*/
|
||||
|
||||
function TableCacheFactory() {
|
||||
}
|
||||
|
||||
module.exports = TableCacheFactory;
|
||||
|
||||
TableCacheFactory.prototype.build = function (settings) {
|
||||
var enabled = settings.tableCacheEnabled || false;
|
||||
var tableCache = null;
|
||||
|
||||
if(enabled) {
|
||||
tableCache = LRU({
|
||||
// store no more than these many items in the cache
|
||||
max: settings.tableCacheMax || 8192,
|
||||
// consider entries expired after these many milliseconds (10 minutes by default)
|
||||
maxAge: settings.tableCacheMaxAge || 1000*60*10
|
||||
});
|
||||
} else {
|
||||
tableCache = new NoCache();
|
||||
}
|
||||
|
||||
return tableCache;
|
||||
};
|
@ -1,101 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
require('../helper');
|
||||
|
||||
var qs = require('querystring');
|
||||
|
||||
var server = require('../../app/server')();
|
||||
var assert = require('../support/assert');
|
||||
|
||||
describe('query-tables-api', function() {
|
||||
|
||||
beforeEach(function(done) {
|
||||
var tableCacheEnabled = global.settings.tableCacheEnabled || false;
|
||||
if(!tableCacheEnabled) {
|
||||
this.skip("tableCache is disabled");
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
function getCacheStatus(callback) {
|
||||
assert.response(
|
||||
server,
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/api/v1/cachestatus'
|
||||
},
|
||||
{
|
||||
status: 200
|
||||
},
|
||||
function(err, res) {
|
||||
callback(null, JSON.parse(res.body));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var request = {
|
||||
url: '/api/v1/sql?' + qs.stringify({
|
||||
q: 'SELECT * FROM untitle_table_4'
|
||||
}),
|
||||
headers: {
|
||||
host: 'vizzuality.cartodb.com'
|
||||
},
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
var RESPONSE_OK = {
|
||||
status: 200
|
||||
};
|
||||
|
||||
it('should create a key in affected tables cache', function(done) {
|
||||
assert.response(server, request, RESPONSE_OK, function(err) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
getCacheStatus(function(err, cacheStatus) {
|
||||
assert.ok(!err, err);
|
||||
assert.equal(cacheStatus.explain.keys, 1);
|
||||
assert.equal(cacheStatus.explain.hits, 0);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should use cache to retrieve affected tables', function(done) {
|
||||
assert.response(server, request, RESPONSE_OK, function(err) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
getCacheStatus(function(err, cacheStatus) {
|
||||
assert.ok(!err, err);
|
||||
assert.equal(cacheStatus.explain.keys, 1);
|
||||
assert.equal(cacheStatus.explain.hits, 1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip cache to retrieve affected tables', function(done) {
|
||||
var masterRequest = {
|
||||
url: '/api/v1/sql?' + qs.stringify({
|
||||
q: 'SELECT * FROM untitle_table_4',
|
||||
api_key: '1234'
|
||||
}),
|
||||
headers: {
|
||||
host: 'vizzuality.cartodb.com'
|
||||
},
|
||||
method: 'GET'
|
||||
};
|
||||
assert.response(server, masterRequest, RESPONSE_OK, function(err) {
|
||||
assert.ok(!err, err);
|
||||
|
||||
getCacheStatus(function(err, cacheStatus) {
|
||||
assert.ok(!err, err);
|
||||
assert.equal(cacheStatus.explain.keys, 1);
|
||||
assert.equal(cacheStatus.explain.hits, 0);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,41 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
require('../../helper');
|
||||
var assert = require('assert');
|
||||
var LRU = require('lru-cache');
|
||||
var NoCache = require('../../../app/utils/no_cache');
|
||||
|
||||
var TableCacheFactory = require('../../../app/utils/table_cache_factory');
|
||||
var factory = new TableCacheFactory();
|
||||
|
||||
describe('TableCacheFactory', function() {
|
||||
|
||||
it('returns a NoCache by default', function() {
|
||||
var tableCache = factory.build({});
|
||||
assert(tableCache instanceof NoCache);
|
||||
});
|
||||
|
||||
it('returns a NoCache if it is disabled in settings', function() {
|
||||
var tableCache = factory.build({tableCacheEnabled: false});
|
||||
assert(tableCache instanceof NoCache);
|
||||
});
|
||||
|
||||
it('returns an LRU if enabled in settings, with its default settings', function() {
|
||||
var tableCache = factory.build({tableCacheEnabled: true});
|
||||
assert(tableCache instanceof LRU);
|
||||
assert.equal(tableCache._max, 8192);
|
||||
assert.equal(tableCache._maxAge, 1000*60*10);
|
||||
});
|
||||
|
||||
it('returns an LRU if enabled in settings, with the passed settings', function() {
|
||||
var tableCache = factory.build({
|
||||
tableCacheEnabled: true,
|
||||
tableCacheMax: 42,
|
||||
tableCacheMaxAge: 1000
|
||||
});
|
||||
assert(tableCache instanceof LRU);
|
||||
assert.equal(tableCache._max, 42);
|
||||
assert.equal(tableCache._maxAge, 1000);
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in new issue