Limit download threads. Fixes #83

This commit is contained in:
Tom MacWright
2012-12-07 11:47:48 -05:00
parent f74b29d93a
commit 9546a6f743
3 changed files with 97 additions and 6 deletions

View File

@@ -23,6 +23,7 @@
<script src='js/lib/d3.latedrag.js'></script>
<script src='js/lib/d3.keybinding.js'></script>
<script src='js/lib/d3-compat.js'></script>
<script src='js/lib/queue.js'></script>
<script src='js/lib/bootstrap-tooltip.js'></script>
<script src='js/id/id.js'></script>

View File

@@ -149,10 +149,6 @@ iD.Connection = function() {
return true;
}
function apiRequestExtent(extent) {
bboxFromAPI(extent, event.load);
}
function loadTiles(projection) {
var scaleExtent = [16, 16],
s = projection.scale(),
@@ -176,10 +172,20 @@ iD.Connection = function() {
projection.invert([x + ts, y + ts])];
}
return tiles
var q = queue(2);
var bboxes = tiles
.filter(tileAlreadyLoaded)
.map(apiExtentBox)
.map(apiRequestExtent);
.forEach(function(e) {
q.defer(bboxFromAPI, e);
});
q.awaitAll(function(err, res) {
var g = iD.Graph();
res.forEach(function(r) { g = g.merge(r); });
event.load(err, g);
});
}
connection.url = function(_) {

84
js/lib/queue.js Normal file
View File

@@ -0,0 +1,84 @@
(function() {
if (typeof module === "undefined") self.queue = queue;
else module.exports = queue;
queue.version = "1.0.0";
function queue(parallelism) {
var queue = {},
active = 0, // number of in-flight deferrals
remaining = 0, // number of deferrals remaining
head, tail, // singly-linked list of deferrals
error = null,
results = [],
await = noop,
awaitAll;
if (arguments.length < 1) parallelism = Infinity;
queue.defer = function() {
if (!error) {
var node = arguments;
node.index = results.push(undefined) - 1;
if (tail) tail.next = node, tail = tail.next;
else head = tail = node;
++remaining;
pop();
}
return queue;
};
queue.await = function(f) {
await = f;
awaitAll = false;
if (!remaining) notify();
return queue;
};
queue.awaitAll = function(f) {
await = f;
awaitAll = true;
if (!remaining) notify();
return queue;
};
function pop() {
if (head && active < parallelism) {
var node = head,
f = node[0],
a = Array.prototype.slice.call(node, 1),
i = node.index;
if (head === tail) head = tail = null;
else head = head.next;
++active;
a.push(function(e, r) {
--active;
if (error != null) return;
if (e != null) {
// clearing remaining cancels subsequent callbacks
// clearing head stops queued tasks from being executed
// setting error ignores subsequent calls to defer
error = e;
remaining = results = head = tail = null;
notify();
} else {
results[i] = r;
if (--remaining) pop();
else notify();
}
});
f.apply(null, a);
}
}
function notify() {
if (error != null) await(error);
else if (awaitAll) await(null, results);
else await.apply(null, [null].concat(results));
}
return queue;
}
function noop() {}
})();