2015-01-30 22:30:13 +08:00
|
|
|
var _ = require('underscore');
|
2015-03-16 07:21:55 +08:00
|
|
|
var step = require('step');
|
2015-01-30 22:30:13 +08:00
|
|
|
var Windshaft = require('windshaft');
|
|
|
|
var os = require('os');
|
|
|
|
var HealthCheck = require('./monitoring/health_check');
|
2011-10-13 19:17:00 +08:00
|
|
|
|
2015-03-16 06:49:32 +08:00
|
|
|
if ( ! process.env.PGAPPNAME )
|
|
|
|
process.env.PGAPPNAME='cartodb_tiler';
|
2014-05-07 22:19:22 +08:00
|
|
|
|
2011-10-13 19:17:00 +08:00
|
|
|
var CartodbWindshaft = function(serverOptions) {
|
2014-02-19 22:27:20 +08:00
|
|
|
// Perform keyword substitution in statsd
|
|
|
|
// See https://github.com/CartoDB/Windshaft-cartodb/issues/153
|
|
|
|
if ( global.environment.statsd ) {
|
|
|
|
if ( global.environment.statsd.prefix ) {
|
2014-02-22 00:25:10 +08:00
|
|
|
var host_token = os.hostname().split('.').reverse().join('.');
|
|
|
|
global.environment.statsd.prefix = global.environment.statsd.prefix.replace(/:host/, host_token);
|
2014-02-19 22:27:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-16 06:44:45 +08:00
|
|
|
var redisPool = serverOptions.redis.pool ||
|
|
|
|
require('redis-mpool')(_.extend(global.environment.redis, {name: 'windshaft:cartodb'}));
|
2014-09-24 17:42:36 +08:00
|
|
|
|
|
|
|
var cartoData = require('cartodb-redis')({pool: redisPool});
|
|
|
|
|
2015-01-30 23:51:09 +08:00
|
|
|
var templateMaps = serverOptions.templateMaps;
|
|
|
|
|
2014-03-04 17:46:15 +08:00
|
|
|
// This is for Templated maps
|
|
|
|
//
|
|
|
|
// "named" is the official, "template" is for backward compatibility up to 1.6.x
|
|
|
|
//
|
|
|
|
var template_baseurl = global.environment.base_url_templated || '(?:/maps/named|/tiles/template)';
|
|
|
|
|
2015-01-23 23:37:38 +08:00
|
|
|
var SurrogateKeysCache = require('./cache/surrogate_keys_cache'),
|
|
|
|
NamedMapsCacheEntry = require('./cache/model/named_maps_entry'),
|
|
|
|
VarnishHttpCacheBackend = require('./cache/backend/varnish_http'),
|
2015-03-16 07:27:14 +08:00
|
|
|
varnishHttpCacheBackend = new VarnishHttpCacheBackend(
|
|
|
|
serverOptions.varnish_host,
|
|
|
|
serverOptions.varnish_http_port
|
|
|
|
),
|
2015-01-23 23:37:38 +08:00
|
|
|
surrogateKeysCache = new SurrogateKeysCache(varnishHttpCacheBackend);
|
|
|
|
|
2015-03-16 06:56:14 +08:00
|
|
|
function invalidateNamedMap (owner, templateName) {
|
|
|
|
surrogateKeysCache.invalidate(new NamedMapsCacheEntry(owner, templateName), function(err) {
|
|
|
|
if (err) {
|
|
|
|
console.warn('Cache: surrogate key invalidation failed');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2015-01-23 23:37:38 +08:00
|
|
|
|
2015-03-16 06:56:14 +08:00
|
|
|
if (serverOptions.varnish_purge_enabled) {
|
2015-01-23 23:37:38 +08:00
|
|
|
['update', 'delete'].forEach(function(eventType) {
|
|
|
|
templateMaps.on(eventType, invalidateNamedMap);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-10-13 22:20:29 +08:00
|
|
|
// boot
|
|
|
|
var ws = new Windshaft.Server(serverOptions);
|
2011-11-30 04:19:10 +08:00
|
|
|
|
2012-10-08 23:26:12 +08:00
|
|
|
// Override getVersion to include cartodb-specific versions
|
|
|
|
var wsversion = ws.getVersion;
|
|
|
|
ws.getVersion = function() {
|
|
|
|
var version = wsversion();
|
|
|
|
version.windshaft_cartodb = require('../../package.json').version;
|
|
|
|
return version;
|
2014-09-24 17:42:53 +08:00
|
|
|
};
|
2012-10-08 23:26:12 +08:00
|
|
|
|
2014-02-19 17:08:25 +08:00
|
|
|
var ws_sendResponse = ws.sendResponse;
|
2014-03-04 21:26:41 +08:00
|
|
|
// GET routes for which we don't want to request any caching.
|
|
|
|
// POST/PUT/DELETE requests are never cached anyway.
|
|
|
|
var noCacheGETRoutes = [
|
|
|
|
'/',
|
2015-04-10 19:39:20 +08:00
|
|
|
'/version',
|
2014-03-04 21:26:41 +08:00
|
|
|
// See https://github.com/CartoDB/Windshaft-cartodb/issues/176
|
2014-03-04 17:46:15 +08:00
|
|
|
serverOptions.base_url_mapconfig,
|
2015-04-27 20:56:38 +08:00
|
|
|
serverOptions.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format',
|
2015-04-10 16:55:46 +08:00
|
|
|
template_baseurl,
|
|
|
|
template_baseurl + '/:template_id',
|
2014-03-04 17:46:15 +08:00
|
|
|
template_baseurl + '/:template_id/jsonp'
|
|
|
|
];
|
2014-02-19 17:08:25 +08:00
|
|
|
ws.sendResponse = function(res, args) {
|
|
|
|
var that = this;
|
|
|
|
var thatArgs = arguments;
|
|
|
|
var statusCode;
|
2014-03-21 20:58:20 +08:00
|
|
|
if ( res._windshaftStatusCode ) {
|
|
|
|
// Added by our override of sendError
|
|
|
|
statusCode = res._windshaftStatusCode;
|
|
|
|
} else {
|
|
|
|
if ( args.length > 2 ) statusCode = args[2];
|
|
|
|
else {
|
|
|
|
statusCode = args[1] || 200;
|
|
|
|
}
|
2014-02-19 17:08:25 +08:00
|
|
|
}
|
|
|
|
var req = res.req;
|
2015-03-16 07:21:55 +08:00
|
|
|
step (
|
2014-02-19 17:08:25 +08:00
|
|
|
function addCacheChannel() {
|
|
|
|
if ( ! req ) {
|
|
|
|
// having no associated request can happen when
|
|
|
|
// using fake response objects for testing layergroup
|
|
|
|
// creation
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-25 00:34:00 +08:00
|
|
|
if ( ! req.params ) {
|
|
|
|
// service requests (/version, /)
|
|
|
|
// have no need for an X-Cache-Channel
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-19 17:08:25 +08:00
|
|
|
if ( statusCode != 200 ) {
|
|
|
|
// We do not want to cache
|
|
|
|
// unsuccessful responses
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-04 21:26:41 +08:00
|
|
|
if ( _.contains(noCacheGETRoutes, req.route.path) ) {
|
2014-03-04 17:46:15 +08:00
|
|
|
//console.log("Skipping cache channel in route:\n" + req.route.path);
|
|
|
|
return false;
|
|
|
|
}
|
2015-03-16 07:27:14 +08:00
|
|
|
//console.log("Adding cache channel to route\n" + req.route.path + " not matching any in:\n" +
|
|
|
|
// mapCreateRoutes.join("\n"));
|
2014-02-19 17:08:25 +08:00
|
|
|
serverOptions.addCacheChannel(that, req, this);
|
|
|
|
},
|
2015-03-16 07:16:36 +08:00
|
|
|
function sendResponse(err/*, added*/) {
|
2014-03-04 17:46:15 +08:00
|
|
|
if ( err ) console.log(err + err.stack);
|
2014-02-19 17:08:25 +08:00
|
|
|
ws_sendResponse.apply(that, thatArgs);
|
2014-03-05 01:04:58 +08:00
|
|
|
return null;
|
|
|
|
},
|
|
|
|
function finish(err) {
|
|
|
|
if ( err ) console.log(err + err.stack);
|
2014-02-19 17:08:25 +08:00
|
|
|
}
|
|
|
|
);
|
2014-01-13 18:20:02 +08:00
|
|
|
};
|
|
|
|
|
2014-03-21 20:58:20 +08:00
|
|
|
var ws_sendError = ws.sendError;
|
|
|
|
ws.sendError = function() {
|
|
|
|
var res = arguments[0];
|
|
|
|
var statusCode = arguments[2];
|
|
|
|
res._windshaftStatusCode = statusCode;
|
|
|
|
ws_sendError.apply(this, arguments);
|
|
|
|
};
|
|
|
|
|
2015-01-21 01:16:09 +08:00
|
|
|
/*******************************************************************************************************************
|
|
|
|
* Routing
|
|
|
|
******************************************************************************************************************/
|
|
|
|
|
2015-04-27 21:01:49 +08:00
|
|
|
var NamedMapsController = require('./controllers/named_maps'),
|
|
|
|
namedMapsController = new NamedMapsController(
|
2015-02-09 21:46:52 +08:00
|
|
|
ws,
|
|
|
|
serverOptions,
|
|
|
|
templateMaps,
|
|
|
|
cartoData,
|
|
|
|
template_baseurl,
|
2015-04-27 20:52:36 +08:00
|
|
|
surrogateKeysCache
|
2015-01-21 01:16:09 +08:00
|
|
|
);
|
2015-04-27 21:01:49 +08:00
|
|
|
namedMapsController.register(ws);
|
2015-01-21 01:16:09 +08:00
|
|
|
|
2015-04-27 20:56:38 +08:00
|
|
|
var TablesExtentApi = require('./api/tables_extent_api');
|
|
|
|
var tablesExtentApi = new TablesExtentApi(serverOptions.pgQueryRunner);
|
|
|
|
|
|
|
|
var NamedStaticMapsController = require('./controllers/named_static_maps');
|
|
|
|
var namedStaticMapsController = new NamedStaticMapsController(
|
|
|
|
ws,
|
2015-04-27 20:59:41 +08:00
|
|
|
serverOptions,
|
2015-04-27 20:56:38 +08:00
|
|
|
templateMaps,
|
|
|
|
ws.staticMapBackend,
|
|
|
|
surrogateKeysCache,
|
|
|
|
tablesExtentApi
|
|
|
|
);
|
|
|
|
namedStaticMapsController.register(ws);
|
|
|
|
|
2015-01-21 01:16:09 +08:00
|
|
|
/*******************************************************************************************************************
|
|
|
|
* END Routing
|
|
|
|
******************************************************************************************************************/
|
|
|
|
|
2015-01-13 19:09:02 +08:00
|
|
|
var healthCheck = new HealthCheck(cartoData, Windshaft.tilelive);
|
2014-11-05 22:06:01 +08:00
|
|
|
ws.get('/health', function(req, res) {
|
|
|
|
var healthConfig = global.environment.health || {};
|
|
|
|
|
|
|
|
if (!!healthConfig.enabled) {
|
|
|
|
var startTime = Date.now();
|
|
|
|
healthCheck.check(healthConfig, function(err, result) {
|
|
|
|
var ok = !err;
|
|
|
|
var response = {
|
|
|
|
enabled: true,
|
|
|
|
ok: ok,
|
|
|
|
elapsed: Date.now() - startTime,
|
|
|
|
result: result
|
|
|
|
};
|
|
|
|
if (err) {
|
|
|
|
response.err = err.message;
|
|
|
|
}
|
|
|
|
res.send(response, ok ? 200 : 503);
|
|
|
|
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
res.send({enabled: false, ok: true}, 200);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-10-13 22:20:29 +08:00
|
|
|
return ws;
|
2014-09-24 17:42:53 +08:00
|
|
|
};
|
2011-10-13 19:17:00 +08:00
|
|
|
|
|
|
|
module.exports = CartodbWindshaft;
|