diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/named_maps.js index 9ab6a78b..8b828f02 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/named_maps.js @@ -28,7 +28,9 @@ NamedMapsController.prototype.register = function(app) { userMiddleware, this.prepareContext, this.getNamedMapProvider(), - this.tile.bind(this), + this.getTile(), + this.getAffectedTablesAndLastUpdatedTime(), + this.respond(), vectorError() ); @@ -43,7 +45,8 @@ NamedMapsController.prototype.register = function(app) { this.getStaticImageOptions(), this.getImage('STATIC_VIZ_MAP'), this.incrementMapViews(), - this.handleImage() + this.getAffectedTablesAndLastUpdatedTime(), + this.respond() ); }; @@ -113,61 +116,27 @@ NamedMapsController.prototype.prepareLayerFilterFromPreviewLayers = function (la }.bind(this); }; -NamedMapsController.prototype.sendResponse = function(req, res, body, headers, namedMapProvider) { - this.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(res.locals.user, namedMapProvider.getTemplateName())); - res.set('Content-Type', headers['content-type'] || headers['Content-Type'] || 'image/png'); - res.set('Cache-Control', 'public,max-age=7200,must-revalidate'); +NamedMapsController.prototype.getTile = function () { + return function getTileMiddleware (req, res, next) { + const { namedMapProvider } = res.locals; - var self = this; + this.tileBackend.getTile(namedMapProvider, req.params, (err, tile, headers, stats) => { + req.profiler.add(stats); - step( - function getAffectedTablesAndLastUpdatedTime() { - namedMapProvider.getAffectedTablesAndLastUpdatedTime(this); - }, - function sendResponse(err, result) { - req.profiler.done('affectedTables'); if (err) { - global.logger.log('ERROR generating cache channel: ' + err); + err.label = 'NAMED_MAP_TILE'; + return next(err); } - if (!result || !!result.tables) { - // we increase cache control as we can invalidate it - res.set('Cache-Control', 'public,max-age=31536000'); - var lastModifiedDate; - if (Number.isFinite(result.lastUpdatedTime)) { - lastModifiedDate = new Date(result.getLastUpdatedAt()); - } else { - lastModifiedDate = new Date(); - } - res.set('Last-Modified', lastModifiedDate.toUTCString()); + res.locals.body = tile; + res.locals.headers = headers; + res.locals.stats = stats; - res.set('X-Cache-Channel', result.getCacheChannel()); - if (result.tables.length > 0) { - self.surrogateKeysCache.tag(res, result); - } - } - res.status(200); - res.send(body); - } - ); + next(); + }); + }.bind(this); }; -NamedMapsController.prototype.tile = function(req, res, next) { - const { namedMapProvider } = res.locals; - - this.tileBackend.getTile(namedMapProvider, req.params, (err, tile, headers, stats) => { - req.profiler.add(stats); - - if (err) { - err.label = 'NAMED_MAP_TILE'; - return next(err); - } - - this.sendResponse(req, res, tile, headers, namedMapProvider); - }); -}; - - var DEFAULT_ZOOM_CENTER = { zoom: 1, center: { @@ -293,7 +262,7 @@ NamedMapsController.prototype.getImage = function (label) { return next(err); } - res.locals.image = image; + res.locals.body = image; res.locals.headers = headers; res.locals.stats = stats; @@ -307,7 +276,7 @@ NamedMapsController.prototype.getImage = function (label) { return next(err); } - res.locals.image = image; + res.locals.body = image; res.locals.headers = headers; res.locals.stats = stats; @@ -341,17 +310,6 @@ NamedMapsController.prototype.incrementMapViews = function () { }.bind(this); }; -NamedMapsController.prototype.handleImage = function () { - return function handleImageMiddleware (req, res) { - const { namedMapProvider, image, headers, stats = {}, format } = res.locals; - - req.profiler.done('render-' + format); - req.profiler.add(stats); - - this.sendResponse(req, res, image, headers, namedMapProvider); - }.bind(this); -}; - function templateZoomCenter(view) { if (!_.isUndefined(view.zoom) && view.center) { return { @@ -382,3 +340,52 @@ function templateBounds(view) { } return false; } + +NamedMapsController.prototype.getAffectedTablesAndLastUpdatedTime = function () { + return function getAffectedTablesAndLastUpdatedTimeMiddleware (req, res, next) { + const { namedMapProvider, headers, user } = res.locals; + + this.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(user, namedMapProvider.getTemplateName())); + res.set('Content-Type', headers['content-type'] || headers['Content-Type'] || 'image/png'); + res.set('Cache-Control', 'public,max-age=7200,must-revalidate'); + + namedMapProvider.getAffectedTablesAndLastUpdatedTime((err, result) => { + req.profiler.done('affectedTables'); + if (err) { + global.logger.log('ERROR generating cache channel: ' + err); + } + + if (!result || !!result.tables) { + // we increase cache control as we can invalidate it + res.set('Cache-Control', 'public,max-age=31536000'); + + var lastModifiedDate; + if (Number.isFinite(result.lastUpdatedTime)) { + lastModifiedDate = new Date(result.getLastUpdatedAt()); + } else { + lastModifiedDate = new Date(); + } + res.set('Last-Modified', lastModifiedDate.toUTCString()); + + res.set('X-Cache-Channel', result.getCacheChannel()); + if (result.tables.length > 0) { + this.surrogateKeysCache.tag(res, result); + } + } + + next(); + }); + }.bind(this); +}; + +NamedMapsController.prototype.respond = function () { + return function respondMiddleware (req, res) { + const { body, stats = {}, format } = res.locals; + + req.profiler.done('render-' + format); + req.profiler.add(stats); + + res.status(200); + res.send(body); + }; +};