Named maps controller adding cache headers

This requires a cache for affected tables as it is hitting db for
every request right now
This commit is contained in:
Raul Ochoa 2015-07-14 20:10:55 +02:00
parent 7247b20686
commit 4aabe9d946
3 changed files with 69 additions and 5 deletions

View File

@ -5,9 +5,10 @@ var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
var cors = require('../middleware/cors');
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
var TablesCacheEntry = require('../cache/model/database_tables_entry');
function NamedMapsController(app, pgConnection, templateMaps, tileBackend, previewBackend, surrogateKeysCache,
tablesExtentApi, userLimitsApi) {
tablesExtentApi, userLimitsApi, queryTablesApi) {
this.app = app;
this.pgConnection = pgConnection;
this.templateMaps = templateMaps;
@ -16,6 +17,7 @@ function NamedMapsController(app, pgConnection, templateMaps, tileBackend, previ
this.surrogateKeysCache = surrogateKeysCache;
this.tablesExtentApi = tablesExtentApi;
this.userLimitsApi = userLimitsApi;
this.queryTablesApi = queryTablesApi;
}
module.exports = NamedMapsController;
@ -29,9 +31,40 @@ NamedMapsController.prototype.register = function(app) {
NamedMapsController.prototype.sendResponse = function(req, res, resource, headers, namedMapProvider) {
this.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(req.context.user, namedMapProvider.getTemplateName()));
res.setHeader('Content-Type', headers['Content-Type']);
res.setHeader('Cache-Control', 'public,max-age=7200,must-revalidate');
this.app.sendResponse(res, [resource, 200]);
res.header('Content-Type', headers['Content-Type']);
res.header('Cache-Control', 'public,max-age=7200,must-revalidate');
var self = this;
var dbName = req.params.dbname;
step(
function getAffectedTablesAndLastUpdatedTime() {
namedMapProvider.getAffectedTablesAndLastUpdatedTime(self.queryTablesApi, this);
},
function sendResponse(err, result) {
req.profiler.done('affectedTables');
if (err) {
console.log('ERROR generating cache channel: ' + err);
}
if (!result || !!result.affectedTables) {
// we increase cache control as we can invalidate it
res.header('Cache-Control', 'public,max-age=31536000');
var lastModifiedDate;
if (Number.isFinite(result.lastUpdatedTime)) {
lastModifiedDate = new Date(result.lastUpdatedTime);
} else {
lastModifiedDate = new Date();
}
res.header('Last-Modified', lastModifiedDate.toUTCString());
var tablesCacheEntry = new TablesCacheEntry(dbName, result.affectedTables);
res.header('X-Cache-Channel', tablesCacheEntry.getCacheChannel());
self.surrogateKeysCache.tag(res, tablesCacheEntry);
}
self.app.sendResponse(res, [resource, 200]);
}
);
};
NamedMapsController.prototype.tile = function(req, res) {

View File

@ -24,6 +24,8 @@ function NamedMapMapConfigProvider(templateMaps, pgConnection, userLimitsApi, ow
// use template after call to mapConfig
this.template = null;
this.affectedTablesAndLastUpdate = null;
// providing
this.err = null;
this.mapConfig = null;
@ -198,3 +200,31 @@ NamedMapMapConfigProvider.prototype.setDBParams = function(cdbuser, params, call
NamedMapMapConfigProvider.prototype.getTemplateName = function() {
return this.templateName;
};
NamedMapMapConfigProvider.prototype.getAffectedTablesAndLastUpdatedTime = function(queryTablesApi, callback) {
var self = this;
if (this.affectedTablesAndLastUpdate !== null) {
return this.affectedTablesAndLastUpdate;
}
step(
function getMapConfig() {
self.getMapConfig(this);
},
function getSql(err, mapConfig) {
assert.ifError(err);
return mapConfig.getLayers().map(function(layer) {
return layer.options.sql;
}).join(';');
},
function getAffectedTables(err, sql) {
assert.ifError(err);
queryTablesApi.getAffectedTablesAndLastUpdatedTime(self.owner, sql, this);
},
function finish(err, result) {
self.affectedTablesAndLastUpdate = result;
return callback(err, result);
}
);
};

View File

@ -221,7 +221,8 @@ module.exports = function(serverOptions) {
previewBackend,
surrogateKeysCache,
tablesExtentApi,
userLimitsApi
userLimitsApi,
queryTablesApi
).register(app);
new controller.NamedMapsAdmin(app, templateMaps, authApi).register(app);