diff --git a/lib/cartodb/server_options.js b/lib/cartodb/server_options.js index dc19b84d..b77cfdd2 100644 --- a/lib/cartodb/server_options.js +++ b/lib/cartodb/server_options.js @@ -201,50 +201,72 @@ module.exports = function(){ // use key to call sql api with sql request if present, else // just return dbname and table name base key - var dbName = req.params.dbname; + var dbName = req.params.dbname; var cacheKey = [ dbName ]; if ( req.params.token ) cacheKey.push(req.params.token); else if ( req.params.sql ) cacheKey.push( me.generateMD5(req.params.sql) ); cacheKey = cacheKey.join(':'); - if ( me.channelCache.hasOwnProperty(cacheKey) ) { - callback(null, me.channelCache[cacheKey]); - return; - } - else if ( req.params.token ) { - // cached cache channel for token-based access should be constructed - // at cache creation time - callback(new Error('missing channel cache for token ' + req.params.token)); - return; - } + var that = this; - if ( ! req.params.sql && ! req.params.token ) { - var cacheChannel = me.buildCacheChannel(dbName, [req.params.table]); - // not worth caching this - callback(null, cacheChannel); - return; - } + Step ( + function checkCached() { + if ( me.channelCache.hasOwnProperty(cacheKey) ) { + callback(null, me.channelCache[cacheKey]); + return; + } + return null; + }, + function extractSQL(err) { + if ( err ) throw err; - if ( ! req.params.sql ) { - callback(new Error("this request doesn't need an X-Cache-Channel generated")); - return; - } + if ( req.params.token ) { + // TODO: cached cache channel for token-based access should + // be constructed at renderer cache creation time + // See http://github.com/CartoDB/Windshaft-cartodb/issues/152 + throw new Error('missing channel cache for token ' + req.params.token); + return; + } + else if ( ! req.params.sql ) { + return null; // no sql + } - var dbName = req.params.dbname; - var username = this.userByReq(req); + // We have sql, and no token... - // strip out windshaft/mapnik inserted sql if present - var sql = req.params.sql.match(/^\((.*)\)\sas\scdbq$/); - sql = (sql != null) ? sql[1] : req.params.sql; + // strip out windshaft/mapnik inserted sql if present + var sql = req.params.sql.match(/^\((.*)\)\sas\scdbq$/); + sql = (sql != null) ? sql[1] : req.params.sql; - me.affectedTables(username, req.params.map_key, sql, function(err, tableNames) { - if ( err ) { callback(err); return; } + return sql; + }, + function findAffectedTables(err, sql) { + if ( err ) throw err; + if ( ! sql ) { + if ( ! req.params.table ) { + throw new Error("this request doesn't need an X-Cache-Channel generated"); + } + return [req.params.table]; + } + var username = that.userByReq(req); + me.affectedTables(username, req.params.map_key, sql, this); + }, + function buildCacheChannel(err, tableNames) { + if ( err ) throw err; + + var dbName = req.params.dbname; var cacheChannel = me.buildCacheChannel(dbName,tableNames); // store for caching from me.generateCacheChannel - me.channelCache[cacheKey] = cacheChannel; - callback(null, cacheChannel); - }); + // (not worth when table was specified in params) + if ( ! req.params.table ) { + me.channelCache[cacheKey] = cacheChannel; + } + return cacheChannel; + }, + function finish(err, cacheChannel) { + callback(err, cacheChannel); + } + ); }; // Set the cache chanel info to invalidate the cache on the frontend server diff --git a/test/acceptance/server.js b/test/acceptance/server.js index 0140f9b1..fed167c6 100644 --- a/test/acceptance/server.js +++ b/test/acceptance/server.js @@ -1111,7 +1111,7 @@ suite('server', function() { var ct = res.headers['content-type']; assert.equal(ct, 'image/png'); var cc = res.headers['x-cache-channel']; - assert(cc); + assert(cc, 'Missing X-Cache-Channel'); var dbname = 'test_cartodb_user_1_db' assert.equal(cc.substring(0, dbname.length), dbname); var jsonquery = cc.substring(dbname.length+1);