add explain cache and cache status route
This commit is contained in:
parent
977f7d0e79
commit
7e074bbc98
@ -20,17 +20,23 @@ var express = require('express')
|
||||
}))
|
||||
, Step = require('step')
|
||||
, csv = require('csv')
|
||||
, crypto = require('crypto')
|
||||
, Meta = require(global.settings.app_root + '/app/models/metadata')
|
||||
, oAuth = require(global.settings.app_root + '/app/models/oauth')
|
||||
, PSQL = require(global.settings.app_root + '/app/models/psql')
|
||||
, ApiKeyAuth = require(global.settings.app_root + '/app/models/apikey_auth')
|
||||
, _ = require('underscore');
|
||||
, _ = require('underscore')
|
||||
, tableCache = {};
|
||||
|
||||
app.use(express.bodyParser());
|
||||
app.enable('jsonp callback');
|
||||
|
||||
// basic routing
|
||||
app.all('/api/v1/sql', function(req, res) { handleQuery(req, res) } );
|
||||
app.all('/api/v1/sql.:f', function(req, res) { handleQuery(req, res) } );
|
||||
app.get('/api/v1/cachestatus', function(req, res) { handleCacheStatus(req, res) } );
|
||||
|
||||
// request handlers
|
||||
function handleQuery(req, res){
|
||||
|
||||
// sanitize input
|
||||
@ -54,6 +60,9 @@ function handleQuery(req, res){
|
||||
// setup step run
|
||||
var start = new Date().getTime();
|
||||
|
||||
// initialise MD5 key of sql for cache lookups
|
||||
var sql_md5 = generateMD5(sql);
|
||||
|
||||
try {
|
||||
if (!_.isString(sql)) throw new Error("You must indicate a sql query");
|
||||
var pg, explain_result;
|
||||
@ -81,14 +90,23 @@ function handleQuery(req, res){
|
||||
// store postgres connection
|
||||
pg = new PSQL(user_id, database, limit, offset);
|
||||
|
||||
// get all the tables
|
||||
// get all the tables from Cache or SQL
|
||||
|
||||
if (!_.isNull(tableCache[sql_md5]) && !_.isUndefined(tableCache[sql_md5])){
|
||||
tableCache[sql_md5].hits++;
|
||||
return true;
|
||||
} else{
|
||||
pg.query("SELECT CDB_QueryTables($$" + sql + "$$)", this);
|
||||
}
|
||||
},
|
||||
function queryResult(err, result){
|
||||
if (err) throw err;
|
||||
|
||||
// store explain result
|
||||
explain_result = result;
|
||||
// store explain result in local Cache
|
||||
if (_.isUndefined(tableCache[sql_md5])){
|
||||
tableCache[sql_md5] = result;
|
||||
tableCache[sql_md5].hits = 1; //initialise hit counter
|
||||
}
|
||||
|
||||
// TODO: refactor formats to external object
|
||||
if (format === 'geojson'){
|
||||
@ -110,7 +128,7 @@ function handleQuery(req, res){
|
||||
// set cache headers
|
||||
res.header('Last-Modified', new Date().toUTCString());
|
||||
res.header('Cache-Control', 'no-cache,max-age=3600,must-revalidate, public');
|
||||
res.header('X-Cache-Channel', generateCacheKey(database,explain_result));
|
||||
res.header('X-Cache-Channel', generateCacheKey(database, tableCache[sql_md5]));
|
||||
|
||||
return result;
|
||||
},
|
||||
@ -147,6 +165,15 @@ function handleQuery(req, res){
|
||||
}
|
||||
}
|
||||
|
||||
function handleCacheStatus(req, res){
|
||||
var tableCacheValues = _.values(tableCache);
|
||||
var totalExplainHits = _.reduce(tableCacheValues, function(memo, res) { return memo + res.hits}, 0);
|
||||
var totalExplainKeys = tableCacheValues.length;
|
||||
|
||||
res.send({explain: {hits: totalExplainHits, keys : totalExplainKeys }});
|
||||
}
|
||||
|
||||
// helper functions
|
||||
function toGeoJSON(data, res, callback){
|
||||
try{
|
||||
var out = {
|
||||
@ -218,6 +245,12 @@ function generateCacheKey(database,tables){
|
||||
return database + ":" + tables.rows[0].cdb_querytables.split(/^\{(.*)\}$/)[1];
|
||||
}
|
||||
|
||||
function generateMD5(data){
|
||||
var hash = crypto.createHash('md5');
|
||||
hash.update(data);
|
||||
return hash.digest('hex');
|
||||
}
|
||||
|
||||
function handleException(err, res){
|
||||
var msg = (global.settings.environment == 'development') ? {error:[err.message], stack: err.stack} : {error:[err.message]}
|
||||
if (global.settings.environment !== 'test'){
|
||||
|
Loading…
Reference in New Issue
Block a user