Skip to content

Commit

Permalink
Add minimal worker pool
Browse files Browse the repository at this point in the history
  • Loading branch information
Anand Thakker committed Aug 6, 2016
1 parent 494590a commit d3d0787
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 23 deletions.
122 changes: 122 additions & 0 deletions debug/shared_workers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<!DOCTYPE html>
<html>
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<link rel='stylesheet' href='../dist/mapbox-gl.css' />
<style>
body { margin: 0; padding: 0; }
html, body, { height: 100%; }
.map {
height: 350px;
width: 350px;
display: inline-block;
}
#checkboxes {
position: absolute;
background: #fff;
top:0;
left:0;
padding:10px;
}
#buffer {
position: absolute;
top:100px;
left:0;
pointer-events: none;
}
#buffer div {
background-color: #fff;
padding: 5px 0;
text-indent: 10px;
white-space: nowrap;
text-shadow:
-1px -1px 0 #fff,
1px -1px 0 #fff,
-1px 1px 0 #fff,
1px 1px 0 #fff;
}
</style>
</head>

<body>
<div class='map'></div>
<div class='map'></div>
<div class='map'></div>
<div class='map'></div>

<div id='checkboxes'>
<input id='show-tile-boundaries-checkbox' name='show-tile-boundaries' type='checkbox'> <label for='show-tile-boundaries'>tile debug</label><br />
<input id='show-symbol-collision-boxes-checkbox' name='show-symbol-collision-boxes' type='checkbox'> <label for='show-symbol-collision-boxes'>collision debug</label><br />
<input id='show-overdraw-checkbox' name='show-overdraw' type='checkbox'> <label for='show-overdraw'>overdraw debug</label><br />
<input id='buffer-checkbox' name='buffer' type='checkbox'> <label for='buffer'>buffer stats</label>
</div>

<div id='buffer' style="display:none">
<em>Waiting for data...</em>
</div>

<script src='mapbox-gl.js'></script>
<script src='access-token.js'></script>

<script>
var containers = document.querySelectorAll('.map')
for (var i = 0; i < containers.length; i++) {
addMap(containers[i]);
}

function addMap (container) {
var map = new mapboxgl.Map({
container: container,
zoom: 12.5,
center: [-77.01866, 38.888],
style: 'mapbox://styles/mapbox/streets-v9',
hash: true
});

map.addControl(new mapboxgl.Navigation());
map.addControl(new mapboxgl.Geolocate());

map.on('load', function() {
map.addSource('geojson', {
"type": "geojson",
"data": "mapbox-gl-test-suite/data/linestring.geojson"
});

map.addLayer({
"id": "route",
"type": "line",
"source": "geojson",
"paint": {
"line-color": "#EC8D8D",
"line-width": {
"base": 1.5,
"stops": [
[
5,
0.75
],
[
18,
32
]
]
}
}
}, 'country-label-lg');
});

map.on('click', function(e) {
if (e.originalEvent.shiftKey) return;
(new mapboxgl.Popup())
.setLngLat(map.unproject(e.point))
.setHTML("<h1>Hello World!</h1>")
.addTo(map);
});
}
</script>

</body>
</html>
11 changes: 6 additions & 5 deletions js/util/dispatcher.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';

var WorkerPool = require('./worker_pool');
var util = require('./util');
var Actor = require('./actor');
var WebWorker = require('./web_worker');

module.exports = Dispatcher;
Dispatcher.workerPool = new WorkerPool();

/**
* Responsible for sending messages from a {@link Source} to an associated
Expand All @@ -17,8 +18,9 @@ function Dispatcher(length, parent) {
this.actors = [];
this.currentActor = 0;
this.id = util.uniqueId();
var workers = Dispatcher.workerPool.acquire(this.id, length);
for (var i = 0; i < length; i++) {
var worker = new WebWorker();
var worker = workers[i];
var actor = new Actor(worker, parent, this.id);
actor.name = "Worker " + i;
this.actors.push(actor);
Expand Down Expand Up @@ -66,9 +68,8 @@ Dispatcher.prototype = {
},

remove: function() {
for (var i = 0; i < this.actors.length; i++) {
this.actors[i].target.terminate();
}
Dispatcher.workerPool.release(this.id);
this.actors = [];
}
};

35 changes: 35 additions & 0 deletions js/util/worker_pool.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

var assert = require('assert');
var WebWorker = require('./web_worker');

module.exports = WorkerPool;

function WorkerPool() {
this.workers = [];
this.active = {};
}

WorkerPool.prototype = {
acquire: function (mapId, workerCount) {
this._resize(workerCount);
this.active[mapId] = workerCount;
return this.workers.slice(0, workerCount);
},

release: function (mapId) {
delete this.active[mapId];
if (Object.keys(this.active).length === 0) {
this.workers.forEach(function (w) { w.terminate(); });
this.workers = [];
}
},

_resize: function (len) {
assert(typeof len === 'number');
while (this.workers.length < len) {
this.workers.push(new WebWorker());
}
}
};

76 changes: 58 additions & 18 deletions test/js/source/worker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test('before', function(t) {
test('load tile', function(t) {
t.test('calls callback on error', function(t) {
var worker = new Worker(_self);
worker['load tile']({
worker['load tile'](0, {
source: 'source',
uid: 0,
url: 'http://localhost:2900/error'
Expand All @@ -42,51 +42,91 @@ test('load tile', function(t) {
test('set layers', function(t) {
var worker = new Worker(_self);

worker['set layers']([
worker['set layers'](0, [
{ id: 'one', type: 'circle', paint: { 'circle-color': 'red' } },
{ id: 'two', type: 'circle', paint: { 'circle-color': 'green' } },
{ id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'blue' } }
]);

t.equal(worker.layers.one.id, 'one');
t.equal(worker.layers.two.id, 'two');
t.equal(worker.layers.three.id, 'three');
t.equal(worker.layers[0].one.id, 'one');
t.equal(worker.layers[0].two.id, 'two');
t.equal(worker.layers[0].three.id, 'three');

t.equal(worker.layers.one.getPaintProperty('circle-color'), 'red');
t.equal(worker.layers.two.getPaintProperty('circle-color'), 'green');
t.equal(worker.layers.three.getPaintProperty('circle-color'), 'blue');
t.equal(worker.layers[0].one.getPaintProperty('circle-color'), 'red');
t.equal(worker.layers[0].two.getPaintProperty('circle-color'), 'green');
t.equal(worker.layers[0].three.getPaintProperty('circle-color'), 'blue');

t.equal(worker.layerFamilies.one.length, 1);
t.equal(worker.layerFamilies.one[0].id, 'one');
t.equal(worker.layerFamilies.two.length, 2);
t.equal(worker.layerFamilies.two[0].id, 'two');
t.equal(worker.layerFamilies.two[1].id, 'three');
t.equal(worker.layerFamilies[0].one.length, 1);
t.equal(worker.layerFamilies[0].one[0].id, 'one');
t.equal(worker.layerFamilies[0].two.length, 2);
t.equal(worker.layerFamilies[0].two[0].id, 'two');
t.equal(worker.layerFamilies[0].two[1].id, 'three');

t.end();
});

test('update layers', function(t) {
var worker = new Worker(_self);

worker['set layers']([
worker['set layers'](0, [
{ id: 'one', type: 'circle', paint: { 'circle-color': 'red' } },
{ id: 'two', type: 'circle', paint: { 'circle-color': 'green' } },
{ id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'blue' } }
]);

worker['update layers']({
worker['update layers'](0, {
one: { id: 'one', type: 'circle', paint: { 'circle-color': 'cyan' } },
two: { id: 'two', type: 'circle', paint: { 'circle-color': 'magenta' } },
three: { id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'yellow' } }
});

t.equal(worker.layers.one.getPaintProperty('circle-color'), 'cyan');
t.equal(worker.layers.two.getPaintProperty('circle-color'), 'magenta');
t.equal(worker.layers.three.getPaintProperty('circle-color'), 'yellow');
t.equal(worker.layers[0].one.getPaintProperty('circle-color'), 'cyan');
t.equal(worker.layers[0].two.getPaintProperty('circle-color'), 'magenta');
t.equal(worker.layers[0].three.getPaintProperty('circle-color'), 'yellow');

t.end();
});

test('update layers isolates different instances\' data', function(t) {
var worker = new Worker(_self);

worker['set layers'](0, [
{ id: 'one', type: 'circle', paint: { 'circle-color': 'red' } },
{ id: 'two', type: 'circle', paint: { 'circle-color': 'green' } },
{ id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'blue' } }
]);

worker['set layers'](1, [
{ id: 'one', type: 'circle', paint: { 'circle-color': 'red' } },
{ id: 'two', type: 'circle', paint: { 'circle-color': 'green' } },
{ id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'blue' } }
]);

worker['update layers'](1, {
one: { id: 'one', type: 'circle', paint: { 'circle-color': 'cyan' } },
two: { id: 'two', type: 'circle', paint: { 'circle-color': 'magenta' } },
three: { id: 'three', ref: 'two', type: 'circle', paint: { 'circle-color': 'yellow' } }
});

t.equal(worker.layers[0].one.id, 'one');
t.equal(worker.layers[0].two.id, 'two');
t.equal(worker.layers[0].three.id, 'three');

t.equal(worker.layers[0].one.getPaintProperty('circle-color'), 'red');
t.equal(worker.layers[0].two.getPaintProperty('circle-color'), 'green');
t.equal(worker.layers[0].three.getPaintProperty('circle-color'), 'blue');

t.equal(worker.layerFamilies[0].one.length, 1);
t.equal(worker.layerFamilies[0].one[0].id, 'one');
t.equal(worker.layerFamilies[0].two.length, 2);
t.equal(worker.layerFamilies[0].two[0].id, 'two');
t.equal(worker.layerFamilies[0].two[1].id, 'three');


t.end();
});


test('after', function(t) {
server.close(t.end);
});

0 comments on commit d3d0787

Please sign in to comment.