Another attempt at avoiding overflowing the callstack on geocoderDataIterator: every tenth time we call a callback, call it via setImmediate to reset the stack
This commit is contained in:
@@ -615,6 +615,9 @@ MBTiles.prototype.putGeocoderData = function(type, shard, data, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
var stackCounter = 0;
|
||||
var stackMax = 10;
|
||||
|
||||
// Implements carmen#geocoderDataIterator method.
|
||||
MBTiles.prototype.geocoderDataIterator = function(type) {
|
||||
var chunkSize = 100;
|
||||
@@ -625,6 +628,20 @@ MBTiles.prototype.geocoderDataIterator = function(type) {
|
||||
var doneSentinel = {};
|
||||
var _this = this;
|
||||
|
||||
// every tenth callback call (globally) do it via setImmediate
|
||||
// to avoid callback loops that blow the callstack
|
||||
var checkStack = function(cb, arg) {
|
||||
if (stackCounter >= stackMax) {
|
||||
stackCounter = 0;
|
||||
setImmediate(function() {
|
||||
cb(arg);
|
||||
})
|
||||
} else {
|
||||
stackCounter += 1;
|
||||
cb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
var sending = false;
|
||||
var sendIfAvailable = function() {
|
||||
if (sending) return;
|
||||
@@ -633,12 +650,12 @@ MBTiles.prototype.geocoderDataIterator = function(type) {
|
||||
while (nextQueue.length && dataQueue.length) {
|
||||
var nextCb = nextQueue.shift(), data;
|
||||
if (dataQueue[0] == doneSentinel) {
|
||||
nextCb({value: undefined, done: true});
|
||||
checkStack(nextCb, {value: undefined, done: true});
|
||||
} else {
|
||||
data = dataQueue.shift();
|
||||
maybeRefillBuffer();
|
||||
|
||||
nextCb({value: {shard: data.shard, data: zlib.inflateSync(data.data)}, done: false});
|
||||
checkStack(nextCb, {value: {shard: data.shard, data: zlib.inflateSync(data.data)}, done: false});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user