Merge pull request #1026 from CartoDB/1024-log-overviews-mapconfig

Log overviews usage during map instantiation
This commit is contained in:
Eneko Lakasta
2018-09-05 12:52:22 +02:00
committed by GitHub
7 changed files with 244 additions and 15 deletions
@@ -152,8 +152,17 @@ function prepareAdapterMapConfig (mapConfigAdapter) {
}
};
mapConfigAdapter.getMapConfig(user, requestMapConfig, params, context, (err, requestMapConfig) => {
mapConfigAdapter.getMapConfig(user,
requestMapConfig,
params,
context,
(err, requestMapConfig, stats = { overviewsUsed : false }) => {
req.profiler.done('anonymous.getMapConfig');
stats.mapType = 'anonymous';
req.profiler.add(stats);
if (err) {
return next(err);
}
@@ -165,8 +165,12 @@ function getTemplate (
params
);
mapConfigProvider.getMapConfig((err, mapConfig, rendererParams) => {
mapConfigProvider.getMapConfig((err, mapConfig, rendererParams, context, stats = {}) => {
req.profiler.done('named.getMapConfig');
stats.mapType = 'named';
req.profiler.add(stats);
if (err) {
return next(err);
}
@@ -11,16 +11,21 @@ MapConfigAdapter.prototype.getMapConfig = function(user, requestMapConfig, param
var i = 0;
var tasksLeft = this.adapters.length;
function next(err, _requestMapConfig) {
let mapConfigStats = {};
function next(err, _requestMapConfig, adapterStats = {}) {
if (err) {
return callback(err);
}
mapConfigStats = Object.assign(mapConfigStats, adapterStats);
if (tasksLeft-- === 0) {
return callback(null, _requestMapConfig);
return callback(null, _requestMapConfig, mapConfigStats);
}
var nextAdapter = self.adapters[i++];
nextAdapter.getMapConfig(user, _requestMapConfig, params, context, next);
}
next(null, requestMapConfig);
next(null, requestMapConfig, mapConfigStats);
};
@@ -20,50 +20,58 @@ MapConfigOverviewsAdapter.prototype.getMapConfig = function (user, requestMapCon
layers.forEach(layer => augmentLayersQueue.defer(this._augmentLayer.bind(this), user, layer, analysesResults));
augmentLayersQueue.awaitAll(function layersAugmentQueueFinish (err, layers) {
augmentLayersQueue.awaitAll(function layersAugmentQueueFinish (err, results) {
if (err) {
return callback(err);
}
const layers = results.map(result => result.layer);
const overviewsAddedToMapconfig = results.some(result => result.overviewsAddedToMapconfig);
if (!layers || layers.length === 0) {
return callback(new Error('Missing layers array from layergroup config'));
}
requestMapConfig.layers = layers;
return callback(null, requestMapConfig);
const stats = { overviewsAddedToMapconfig };
return callback(null, requestMapConfig, stats);
});
};
MapConfigOverviewsAdapter.prototype._augmentLayer = function (user, layer, analysesResults, callback) {
let overviewsAddedToMapconfig = false;
if (layer.type !== 'mapnik' && layer.type !== 'cartodb') {
return callback(null, layer);
return callback(null, { layer, overviewsAddedToMapconfig });
}
this.overviewsMetadataBackend.getOverviewsMetadata(user, layer.options.sql, (err, metadata) => {
if (err) {
return callback(err, layer);
return callback(err, { layer, overviewsAddedToMapconfig });
}
if (_.isEmpty(metadata)) {
return callback(null, layer);
return callback(null, { layer, overviewsAddedToMapconfig });
}
var filters = getFilters(analysesResults, layer);
overviewsAddedToMapconfig = true;
if (!filters) {
layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, {
overviews: metadata
}));
return callback(null, layer);
return callback(null, { layer, overviewsAddedToMapconfig });
}
var unfilteredQuery = getUnfilteredQuery(analysesResults, layer);
this.filterStatsBackend.getFilterStats(user, unfilteredQuery, filters, function (err, stats) {
if (err) {
return callback(null, layer);
return callback(null, { layer, overviewsAddedToMapconfig });
}
layer.options = Object.assign({}, layer.options, getQueryRewriteData(layer, analysesResults, {
@@ -71,7 +79,7 @@ MapConfigOverviewsAdapter.prototype._augmentLayer = function (user, layer, analy
filter_stats: stats
}));
return callback(null, layer);
return callback(null, { layer, overviewsAddedToMapconfig });
});
});
};
@@ -99,7 +99,7 @@ module.exports = class NamedMapMapConfigProvider extends BaseMapConfigProvider {
const { user, rendererParams } = this;
this.mapConfigAdapter.getMapConfig(
user, requestMapConfig, rendererParams, context, (err, mapConfig) => {
user, requestMapConfig, rendererParams, context, (err, mapConfig, stats = {}) => {
if (err) {
this.err = err;
return callback(err);
@@ -108,7 +108,7 @@ module.exports = class NamedMapMapConfigProvider extends BaseMapConfigProvider {
this.mapConfig = (mapConfig === null) ? null : new MapConfig(mapConfig, context.datasource);
this.analysesResults = context.analysesResults || [];
return callback(null, this.mapConfig, this.rendererParams, this.context);
return callback(null, this.mapConfig, this.rendererParams, this.context, stats);
});
});
});
+78
View File
@@ -72,6 +72,7 @@ describe('overviews metadata', function() {
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
var parsedBody = JSON.parse(res.body);
assert.equal(res.headers['x-layergroup-id'], parsedBody.layergroupid);
expected_token = parsedBody.layergroupid;
@@ -113,6 +114,83 @@ describe('overviews metadata', function() {
}
);
});
describe('Overviews Flags', function () {
it("Overviews used", function (done) {
var layergroup = {
version: '1.0.0',
layers: [overviews_layer, non_overviews_layer]
};
var layergroup_url = '/api/v1/map';
var expected_token;
step(
function do_post() {
var next = this;
assert.response(server, {
url: layergroup_url,
method: 'POST',
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function (res) {
assert.equal(res.statusCode, 200, res.body);
const headers = JSON.parse(res.headers['x-tiler-profiler']);
assert.ok(headers.overviewsAddedToMapconfig);
assert.equal(headers.mapType, 'anonymous');
const parsedBody = JSON.parse(res.body);
expected_token = parsedBody.layergroupid;
next();
});
},
function finish(err) {
keysToDelete['map_cfg|' + LayergroupToken.parse(expected_token).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
done(err);
}
);
});
it("Overviews NOT used", function (done) {
var layergroup = {
version: '1.0.0',
layers: [non_overviews_layer]
};
var layergroup_url = '/api/v1/map';
var expected_token;
step(
function do_post() {
var next = this;
assert.response(server, {
url: layergroup_url,
method: 'POST',
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function (res) {
assert.equal(res.statusCode, 200, res.body);
const headers = JSON.parse(res.headers['x-tiler-profiler']);
assert.equal(headers.overviewsAddedToMapconfig, false);
assert.equal(headers.mapType, 'anonymous');
const parsedBody = JSON.parse(res.body);
expected_token = parsedBody.layergroupid;
next();
});
},
function finish(err) {
keysToDelete['map_cfg|' + LayergroupToken.parse(expected_token).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
done(err);
}
);
});
});
});
describe('overviews metadata with filters', function() {
@@ -176,4 +176,129 @@ describe('overviews metadata for named maps', function() {
}
);
});
describe('Overviews Flags', function() {
it("Overviews used", function (done) {
step(
function postTemplate() {
var next = this;
assert.response(server, {
url: '/api/v1/map/named?api_key=1234',
method: 'POST',
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(template)
}, {}, function (res, err) {
next(err, res);
});
},
function instantiateTemplate(err) {
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/api/v1/map/named/' + templateId,
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
}
}, {},
function (res, err) {
return next(err, res);
});
},
function checkFlags(err, res) {
assert.ifError(err);
var next = this;
var parsedBody = JSON.parse(res.body);
keysToDelete['map_cfg|' + LayergroupToken.parse(parsedBody.layergroupid).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
const headers = JSON.parse(res.headers['x-tiler-profiler']);
assert.ok(headers.overviewsAddedToMapconfig);
assert.equal(headers.mapType, 'named');
next();
},
function finish(err) {
done(err);
}
);
});
it("Overviews NOT used", function (done) {
const nonOverviewsTemplateId = 'non-overviews-template';
var nonOverviewsTemplate = {
version: '0.0.1',
name: nonOverviewsTemplateId,
auth: { method: 'open' },
layergroup: {
version: '1.0.0',
layers: [non_overviews_layer]
}
};
step(
function postTemplate() {
var next = this;
assert.response(server, {
url: '/api/v1/map/named?api_key=1234',
method: 'POST',
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(nonOverviewsTemplate)
}, {}, function (res, err) {
next(err, res);
});
},
function instantiateTemplate(err) {
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/api/v1/map/named/' + nonOverviewsTemplateId,
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
}
}, {},
function (res, err) {
return next(err, res);
});
},
function checkFlags(err, res) {
assert.ifError(err);
var next = this;
var parsedBody = JSON.parse(res.body);
keysToDelete['map_cfg|' + LayergroupToken.parse(parsedBody.layergroupid).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
const headers = JSON.parse(res.headers['x-tiler-profiler']);
assert.equal(headers.overviewsAddedToMapconfig, false);
assert.equal(headers.mapType, 'named');
next();
},
function finish(err) {
done(err);
}
);
});
});
});