0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-29 23:16:30 +01:00
nodejs/test/mjsunit/test-wait-ordering.js
Ryan aefbd57514 Add stack to promise.wait().
The problem was that if promise A was waiting and promise B was created and
then also told to wait (from some callback coming off the event loop), and
then promise A finished, promise B's wait would return. Promise A's wait
would not return until promise B was finished. This is incorrect.

To solve this issue properly, one probably needs to allocate separate
execution stacks. I use, instead, Poor Man's Coroutines. We continue to use
the main execution stack and force promises created most recently to return
first.

That is even if Promise A finishes first, neither wait() returns. Not until
Promise B finishes, will its wait() return. After that is complete, Promise
A's wait() will return.

This introduces the problem of growing the "wait stack" infinitely. Thus
I've added a strong warning to the documentation only to use this operation
sparingly. require() and include() seem to be the proper use case for such a
thing: they are called usually at program start up - they don't take too
long to finish and they won't be called so often.

Let's experiment with this stop-gap. If the infinite promise stack becomes a
problem for many, then I will remove promise.wait() entirely or perhaps only
use it for thread pool events.
2009-09-03 10:48:39 +02:00

31 lines
842 B
JavaScript

include("mjsunit.js");
function timer (t) {
var promise = new node.Promise();
setTimeout(function () {
promise.emitSuccess();
}, t);
return promise;
}
order = 0;
var a = new Date();
function test_timeout_order(delay, desired_order) {
timer(0).addCallback(function() {
timer(delay).wait()
var b = new Date();
assertTrue(b - a >= delay);
order++;
// A stronger assertion would be that the ordering is correct.
// With Poor Man's coroutines we cannot guarentee that.
// Replacing wait() with actual coroutines would solve that issue.
// assertEquals(desired_order, order);
});
}
test_timeout_order(10000, 6); // Why does this have the proper order??
test_timeout_order(5000, 5);
test_timeout_order(4000, 4);
test_timeout_order(3000, 3);
test_timeout_order(2000, 2);
test_timeout_order(1000, 1);