--
You received this message because you are subscribed to the Google Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com.
To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nodejs?hl=en.
--
--
--
--
setTimeout, on the other hand, does not. Each timeout value uses its
own c-layer timer object, so if you do this:
setTimeout(A, 0)
setTimeout(B, 1)
then conceivably A might fire either before or after B.
nextTick always fires before any setTimeout timers. The process is:
1. Run all the code from top to bottom
2. If there's nothing on the event loop at all, exit.
3. Process any nextTicks
4. Wait for events (setTimeout, http requests, callbacks from fs
functions, etc.)
--
Technically, its not recursion ;).. but yeah it's about as close to a while loop that you can get without blocking
> If the events get dequeued as Isaac describes it, there is a
> starvation problem.
> As I understand it, there are two queues:
>
> * a nextTick queue with higher priority
> * an event queue with lower priority.
>
> If I understand well, the event queue is only processed if the
> nextTick queue is empty and the logic is something like:
>
> while (nextTickQueue.length || eventQueue.length) {
> if (nextTickQueue.length)
> processEvent(nextTickQueue.shift());
> else
> processEvent(eventQueue.shift());
> }
No. It's not so. When node grabs the nextTick queue to service it, it has a finite length (say 20 items), any additional items that might be added to the nextick queue while it's being serviced, won't be serviced until the next tick:
So it will be more like so:
1.- grab the nextTick queue .length.
2.- remove and service the first (length) items in it. (some more items might be added as a result, but these won't be serviced yet)
3.- service other events: timers, i/o, async, etc.
4.- goto 1
> (...)
--
Jorge.
> Thanks Jorge,
>
> This corresponds more or less to the second loop that I posted (the
> one that reallocates the queues).
>
> I was a bit confused by the statement: "nextTick always fires before
> any setTimeout timers". I think that it should read "nextTick always
> fires before any setTimeout timers created during the same tick". A
> timeout that was initiated during a previous tick may fire before
> nextTick!
>
> Is this right?
Yes it is. Given this:
setTimeout(f, 0);
process.nextTick(g);
function g () { process.nextTick(h) }
- g() will run before f(), but
- h() may run before or after f().
Oh, and wrt timers: node.js is *the*only* JS platform that I know where this
setTimeout( f, 1 );
setTimeout( g, 2 );
may eventually trigger g() before f(). I consider it a bug, but ry thinks different... :-)
--
Jorge.
That is correct. Timers are checked after nextTick callbacks, but any
nextTick callbacks added by that batch of nextTick callbacks won't be
processed in the same tick as their parents, so those timers may fire.
> Oh, and wrt timers: node.js is *the*only* JS platform that I know where this
>
> setTimeout( f, 1 );
> setTimeout( g, 2 );
>
> may eventually trigger g() before f(). I consider it a bug, but ry thinks different... :-)
Actually, this has never been guaranteed by any JavaScript platform
that I'm aware of, and at least in IE, Firefox, and Safari circa 2008,
it was quite common to see low-valued timers firing in that way. I
have been bitten hard by the assumption that timers will always be in
a predictable order. On most browsers, any timeout value less than
some minimum value is silently changed to that minimum (50ms, last I
checked, which was quite some time ago).
Node's setTimeout is remarkably precise, in fact.
I've never seen that happen in any browser, only in node.js.
Here's a test.js for node and a bookmarklet to run the test in any browser:
<https://github.com/xk/nodeSnippets/blob/master/timers_ORDER.js>
node.js fails but I've yet to find a browser that fails.
> I
> have been bitten hard by the assumption that timers will always be in
> a predictable order. On most browsers, any timeout value less than
> some minimum value is silently changed to that minimum (50ms, last I
> checked, which was quite some time ago).
Yes, but that's another story, isn't it ?
--
Jorge.
> I'd be on ry's side here. I don't think that people should rely on
> assumptions like these when writing non-deterministic code.
OTOH, if that's what every browser out there does, then it's the expected behaviour, then node.js should perhaps (better) do it that way too.
--
Jorge.
Also, don't you expect nextTick()s to fire orderly ? I do !
--
Jorge.
nextTick is predictably ordered because it is explicitly just "Put
this function on the event loop to run at the end of this pass, at the
highest priority." It's for cases where you want to mimic async
behavior, but not take unnecessary time (for instance, if you find
something from cache that would normally require a db lookup.)
That browser setTimeout test doesn't actually run into any cases that
are particularly tricky. I've seen this behavior on the Yahoo
Application Platform front-end code where we had several thousand
events firing over the course of a session, making heavy use of
setTimeout(fn, 0). In the first iteration, we relied on certain
things being in-order, and had strange bugs as a result of the order
being unpredictable <1% of the time, only when there were many many
dom nodes being updated around the same time.
I was never able to reliably reproduce it in any minified contrived
test-case. So, I guess there's an element of FUD in what I'm saying
here, and I apologize for that. My only defense is that I do have
first-hand experience that it was a real issue we saw in multiple
browsers, and refactoring the code to accept out-of-order setTimeout
firing made the problems disappear.
Also, it's really tricky and complex to guarantee order. In the end,
it's not worth the effort.