-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Stack overflow in async.queue #413
Comments
It happened when too many synchronous tasks were queued. Fix caolan#413
Isn't the problem here that you're invoking the callback synchronously? (which you shouldn't do, as per Effective JS item 67) |
Indeed, you are correct! |
Sorry to resurrect something thats been closed, but I'm having a similar issue and can't understand why the test file is incorrect? What is the correct way of calling the callback? Again, sorry to be a pain |
The basic takeaway is that you should not call synchronously a callback. If a function takes a callback, it means that it should call it on another tick. If your code is purely synchronous, you should use |
Paul, Thanks for getting back to me, and thanks for clarifying! I must have some not-so-obvious recursive function call somewhere in my code as I'm still struggling with the same error. Austin |
I fully understand the premise and the recommendation, but this does put the onus on the user of the library for something that just isn't all that well-enough understood. Common knowledge about item 67 of Effective JS should prevail in an ideal world, but the amount of code written that short-circuits the logic of a function due to preconditions is going to trump that every time IMHO, e.g. var process = function (data, cb) {
if (!data || /* data does not pass some sanity test */) {
cb();
} else {
// continue with async call
}
}
var queue = async.queue(process, 1);
var i;
for (i = 0; i < 10000; i++) {
queue.push(i);
}
// Stack Overflow It is understood here that the solution is var process = function (data, cb) {
if (!data || /* data does not pass some sanity test */) {
async.setImmediate(cb()); // process.nextTick() or similar
} else {
// continue with async call
}
} Think about the number of usages in the wild for |
Generating minimal performance penatly is the real issue. While the library could easily defer all callbacks inside I am drafting a couple solutions to the problem, I will have a proposal in a few days or so. |
When too many tasks are added synchronously to an
async.queue
, the queue will then process all of them in the same stack, which causes a stack overflow.Here is a gist example.
Here is a failing test case (add this to
test.test-async.js
):that can be fixed by replacing
async.js:725
:by
(related to issue #117) But this unfortunately breaks the
queue events
test, as the events are then emitted in the wrong order:Does anyone have a real fix for this issue?
The text was updated successfully, but these errors were encountered: