Use dynamic pool of map instances to reduce waiting times (issue #3)

This commit is contained in:
Petr Sloup 2016-03-03 19:41:29 +01:00
parent 4f9b8c1a1b
commit dc096012ef
2 changed files with 76 additions and 78 deletions

View file

@ -12,11 +12,11 @@
},
"dependencies": {
"async": "1.5.2",
"async-lock": "0.3.8",
"advanced-pool": "0.3.1",
"clone": "1.0.2",
"cors": "2.7.1",
"express": "4.13.4",
"mapbox-gl-native": "3.0.2-earcut",
"mapbox-gl-native": "3.0.2",
"mbtiles": "0.8.2",
"morgan": "1.7.0",
"nomnom": "1.8.1",

View file

@ -1,7 +1,7 @@
'use strict';
var async = require('async'),
asyncLock = require('async-lock'),
advancedPool = require('advanced-pool'),
crypto = require('crypto'),
fs = require('fs'),
path = require('path'),
@ -32,8 +32,6 @@ mbgl.on('message', function(e) {
});
module.exports = function(maps, options, prefix) {
var lock = new asyncLock();
var app = express().disable('x-powered-by'),
domains = options.domains,
tilePath = '/{z}/{x}/{y}.{format}';
@ -46,9 +44,11 @@ module.exports = function(maps, options, prefix) {
sources: {},
tileJSON: {}
};
if (!maps[prefix]) {
var createRenderer = function(ratio) {
return new mbgl.Map({
var styleJSON;
var createPool = function(ratio, min, max) {
var createRenderer = function(ratio, createCallback) {
var renderer = new mbgl.Map({
ratio: ratio,
request: function(req, callback) {
var protocol = req.url.split(':')[0];
@ -115,12 +115,20 @@ module.exports = function(maps, options, prefix) {
}
}
});
renderer.load(styleJSON);
createCallback(null, renderer);
};
return new advancedPool.Pool({
min: min,
max: max,
create: createRenderer.bind(null, ratio),
destroy: function(renderer) {
renderer.release();
}
});
};
map.renderers[1] = createRenderer(1);
map.renderers[2] = createRenderer(2);
map.renderers[3] = createRenderer(3);
var styleJSON = require(path.join(rootPath, styleUrl));
styleJSON = require(path.join(rootPath, styleUrl));
map.tileJSON = {
'tilejson': '2.0.0',
@ -160,15 +168,13 @@ module.exports = function(maps, options, prefix) {
});
async.parallel(queue, function(err, results) {
map.renderers.forEach(function(renderer) {
renderer.load(styleJSON);
});
// TODO: make pool sizes configurable
map.renderers[1] = createPool(1, 2, 8);
map.renderers[2] = createPool(2, 2, 4);
map.renderers[3] = createPool(3, 2, 4);
});
maps[prefix] = map;
} else {
map = maps[prefix];
}
var tilePattern = tilePath
.replace(/\.(?!.*\.)/, ':scale(' + SCALE_PATTERN + ')?.')
@ -186,17 +192,10 @@ module.exports = function(maps, options, prefix) {
return res.status(404).send('Invalid format');
}
var pool = map.renderers[scale];
pool.acquire(function(err, renderer) {
var mbglZ = Math.max(0, z - 1);
var renderer = map.renderers[scale];
var params = {
/*
debug: {
tileBorders: true,
parseStatus: true,
timestamps: true,
collision: true
},
*/
zoom: mbglZ,
center: [lon, lat],
width: width,
@ -206,9 +205,8 @@ module.exports = function(maps, options, prefix) {
params.width *= 2;
params.height *= 2;
}
lock.acquire(renderer, function(done) {
renderer.render(params, function(err, data) {
done();
pool.release(renderer);
if (err) console.log(err);
var image = sharp(data, {