-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: