Always generate X-Cache-Channel for token-based tile responses

Closes #152
This commit is contained in:
Sandro Santilli 2014-02-19 10:08:25 +01:00
parent 36a135f02b
commit 6c6f3d02f6
6 changed files with 82 additions and 42 deletions

View File

@ -5,6 +5,10 @@ Enhancements:
* Use log4js logger (#138) * Use log4js logger (#138)
Bug fixes:
* Always generate X-Cache-Channel for token-based tile responses (#152)
1.8.0 -- 2014-02-18 1.8.0 -- 2014-02-18
------------------- -------------------

View File

@ -46,20 +46,36 @@ var CartodbWindshaft = function(serverOptions) {
return version; return version;
} }
// Override sendError to drop added cache headers (if any) var ws_sendResponse = ws.sendResponse;
// See http://github.com/CartoDB/Windshaft-cartodb/issues/107 ws.sendResponse = function(res, args) {
var ws_sendError = ws.sendError; var that = this;
ws.sendError = function(res) { var thatArgs = arguments;
// NOTE: the "res" object will have no _headers when var statusCode;
// faked by Windshaft, see if ( args.length > 2 ) statusCode = args[2];
// http://github.com/CartoDB/Windshaft-cartodb/issues/109 else {
// statusCode = args[1] || 200;
if ( res._headers ) {
delete res._headers['cache-control'];
delete res._headers['last-modified'];
delete res._headers['x-cache-channel'];
} }
ws_sendError.apply(this, arguments); var req = res.req;
Step (
function addCacheChannel() {
if ( ! req ) {
// having no associated request can happen when
// using fake response objects for testing layergroup
// creation
return false;
}
if ( statusCode != 200 ) {
// We do not want to cache
// unsuccessful responses
return false;
}
serverOptions.addCacheChannel(that, req, this);
},
function sendResponse(err, added) {
if (added && req.profiler) req.profiler.done('addCacheChannel');
ws_sendResponse.apply(that, thatArgs);
}
);
}; };
/** /**
@ -74,9 +90,9 @@ var CartodbWindshaft = function(serverOptions) {
function(err, data){ function(err, data){
if (err){ if (err){
ws.sendError(res, {error: err.message}, 500, 'GET INFOWINDOW', err); ws.sendError(res, {error: err.message}, 500, 'GET INFOWINDOW', err);
//res.send({error: err.message}, 500); //ws.sendResponse(res, [{error: err.message}, 500]);
} else { } else {
res.send({infowindow: data}, 200); ws.sendResponse(res, [{infowindow: data}, 200]);
} }
} }
); );
@ -95,9 +111,9 @@ var CartodbWindshaft = function(serverOptions) {
function(err, data){ function(err, data){
if (err){ if (err){
ws.sendError(res, {error: err.message}, 500, 'GET MAP_METADATA', err); ws.sendError(res, {error: err.message}, 500, 'GET MAP_METADATA', err);
//res.send(err.message, 500); //ws.sendResponse(res, [err.message, 500]);
} else { } else {
res.send({map_metadata: data}, 200); ws.sendResponse(res, [{map_metadata: data}, 200]);
} }
} }
); );
@ -116,9 +132,9 @@ var CartodbWindshaft = function(serverOptions) {
function sendResponse(err, data){ function sendResponse(err, data){
if (err){ if (err){
ws.sendError(res, {error: err.message}, 500, 'DELETE CACHE', err); ws.sendError(res, {error: err.message}, 500, 'DELETE CACHE', err);
//res.send(500); //ws.sendResponse(res, [500]);
} else { } else {
res.send({status: 'ok'}, 200); ws.sendResponse(res, [{status: 'ok'}, 200]);
} }
} }
); );
@ -177,7 +193,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'POST TEMPLATE', err); ws.sendError(res, response, statusCode, 'POST TEMPLATE', err);
} else { } else {
res.send(response, 200); ws.sendResponse(res, [response, 200]);
} }
} }
); );
@ -234,7 +250,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'PUT TEMPLATE', err); ws.sendError(res, response, statusCode, 'PUT TEMPLATE', err);
} else { } else {
res.send(response, 200); ws.sendResponse(res, [response, 200]);
} }
} }
); );
@ -292,7 +308,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'GET TEMPLATE', err); ws.sendError(res, response, statusCode, 'GET TEMPLATE', err);
} else { } else {
res.send(response, 200); ws.sendResponse(res, [response, 200]);
} }
} }
); );
@ -342,7 +358,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'DELETE TEMPLATE', err); ws.sendError(res, response, statusCode, 'DELETE TEMPLATE', err);
} else { } else {
res.send('', 204); ws.sendResponse(res, ['', 204]);
} }
} }
); );
@ -382,7 +398,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'GET TEMPLATE LIST', err); ws.sendError(res, response, statusCode, 'GET TEMPLATE LIST', err);
} else { } else {
res.send(response, statusCode); ws.sendResponse(res, [response, statusCode]);
} }
} }
); );
@ -531,7 +547,7 @@ var CartodbWindshaft = function(serverOptions) {
} }
ws.sendError(res, response, statusCode, 'POST INSTANCE TEMPLATE', err); ws.sendError(res, response, statusCode, 'POST INSTANCE TEMPLATE', err);
} else { } else {
res.send(response, 200); ws.sendResponse(res, [response, 200]);
} }
if ( req.profiler && req.profiler.statsd_client) { if ( req.profiler && req.profiler.statsd_client) {
req.profiler.sendStats(); req.profiler.sendStats();

View File

@ -197,7 +197,7 @@ module.exports = function(){
return hash.digest('hex'); return hash.digest('hex');
} }
me.generateCacheChannel = function(req, callback){ me.generateCacheChannel = function(app, req, callback){
// use key to call sql api with sql request if present, else // use key to call sql api with sql request if present, else
// just return dbname and table name base key // just return dbname and table name base key
@ -225,10 +225,33 @@ module.exports = function(){
// TODO: cached cache channel for token-based access should // TODO: cached cache channel for token-based access should
// be constructed at renderer cache creation time // be constructed at renderer cache creation time
// See http://github.com/CartoDB/Windshaft-cartodb/issues/152 // See http://github.com/CartoDB/Windshaft-cartodb/issues/152
if ( ! app.mapStore ) {
throw new Error('missing channel cache for token ' + req.params.token); throw new Error('missing channel cache for token ' + req.params.token);
return; return;
} }
else if ( ! req.params.sql ) { var next = this;
var mapStore = app.mapStore;
Step(
function loadFromStore() {
mapStore.load(req.params.token, this);
},
function getSQL(err, mapConfig) {
if ( err ) throw err;
var sql = [];
_.each(mapConfig.obj().layers, function(lyr) {
sql.push(lyr.options.sql);
});
sql = sql.join(';');
return sql;
},
function finish(err, sql) {
next(err, sql);
}
);
return;
}
if ( ! req.params.sql ) {
return null; // no sql return null; // no sql
} }
@ -278,7 +301,7 @@ module.exports = function(){
// @param cb function(err, channel) will be called when ready. // @param cb function(err, channel) will be called when ready.
// the channel parameter will be null if nothing was added // the channel parameter will be null if nothing was added
// //
me.addCacheChannel = function(req, cb) { me.addCacheChannel = function(app, req, cb) {
// skip non-GET requests, or requests for which there's no response // skip non-GET requests, or requests for which there's no response
if ( req.method != 'GET' || ! req.res ) { cb(null, null); return; } if ( req.method != 'GET' || ! req.res ) { cb(null, null); return; }
var res = req.res; var res = req.res;
@ -302,7 +325,7 @@ module.exports = function(){
} }
res.header('Last-Modified', lastUpdated.toUTCString()); res.header('Last-Modified', lastUpdated.toUTCString());
me.generateCacheChannel(req, function(err, channel){ me.generateCacheChannel(app, req, function(err, channel){
if ( ! err ) { if ( ! err ) {
res.header('X-Cache-Channel', channel); res.header('X-Cache-Channel', channel);
cb(null, channel); cb(null, channel);
@ -722,10 +745,7 @@ module.exports = function(){
dbport: global.environment.postgres.port dbport: global.environment.postgres.port
}); });
that.addCacheChannel(req, function(err) { callback(null, req);
if (req.profiler) req.profiler.done('addCacheChannel');
callback(err, req);
});
} }
); );
}; };

10
npm-shrinkwrap.json generated
View File

@ -10,8 +10,8 @@
"version": "1.3.3" "version": "1.3.3"
}, },
"windshaft": { "windshaft": {
"version": "0.18.2", "version": "0.19.0",
"from": "http://github.com/CartoDB/Windshaft/tarball/0.18.2", "from": "http://github.com/CartoDB/Windshaft/tarball/0.19.0-rc1",
"dependencies": { "dependencies": {
"grainstore": { "grainstore": {
"version": "0.18.0", "version": "0.18.0",
@ -429,15 +429,15 @@
} }
} }
}, },
"semver": {
"version": "1.1.4"
},
"strftime": { "strftime": {
"version": "0.6.2" "version": "0.6.2"
}, },
"redis": { "redis": {
"version": "0.8.6" "version": "0.8.6"
}, },
"semver": {
"version": "1.1.4"
},
"mocha": { "mocha": {
"version": "1.14.0", "version": "1.14.0",
"dependencies": { "dependencies": {

View File

@ -24,7 +24,7 @@
"dependencies": { "dependencies": {
"node-varnish": "http://github.com/Vizzuality/node-varnish/tarball/v0.2.0", "node-varnish": "http://github.com/Vizzuality/node-varnish/tarball/v0.2.0",
"underscore" : "~1.3.3", "underscore" : "~1.3.3",
"windshaft" : "http://github.com/CartoDB/Windshaft/tarball/0.18.2", "windshaft" : "http://github.com/CartoDB/Windshaft/tarball/0.19.0-rc1",
"step": "0.0.x", "step": "0.0.x",
"request": "2.9.202", "request": "2.9.202",
"cartodb-redis": "~0.3.0", "cartodb-redis": "~0.3.0",

View File

@ -665,7 +665,7 @@ suite('multilayer', function() {
}); });
// See https://github.com/CartoDB/Windshaft-cartodb/issues/152 // See https://github.com/CartoDB/Windshaft-cartodb/issues/152
test.skip("x-cache-channel still works for GETs after tiler restart", function(done) { test("x-cache-channel still works for GETs after tiler restart", function(done) {
var layergroup = { var layergroup = {
version: '1.0.0', version: '1.0.0',