You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
timer,domain: timers don't maintain order after exception #1271
Yes I definitely think that timers should guarantee order to the extent that browsers do, currently they don't do that even in normal code (normal as in not using domains) and code that assumes e.g. setTimeout(..., 5) fires before setTimeout(..., 1000).is broken in node but works fine in browsers.
I'm pretty sure this has something to do with the fact that after an error timers.js re-schedules to start processing again on the next tick, but doesn't actually stop processing presently: https://github.com/nodejs/io.js/blob/master/lib/timers.js#L100
This diff fixes the test, but causes other problems, so I'm confused.
@trevnorris@bnoordhuis ... running this against master currently, given about 100 runs each on @bnoordhuis' original and @trevnorris' revised version and I'm not seeing any variability in the ordering over timer events. Could this one have been fixed?
I suppose. I suspect unless someone else throws a considerable amount of time at it, this will just go away when domains are likely removed in a couple years.
I'm able to help with the timers side of things if anyone wants to take a look into it.
Maybe @misterdjules would actually be the best to take a look?
I took a crack at this and hopefully what I found is useful :-)
The callbacks are stored in an associative array that is indexed by the number of milliseconds.
So list[1] is created for 1ms callbacks, and list[2] is created for 2ms callbacks.
Both these lists are in the queue for the current tick.
When list[1] encounters an unhandled exception, only the 1ms list is postponed to the next tick.
However, list[2] still exists on the current tick and will go through.
The solution seems to be skip all further list[x] to the next tick.
I tested this on linux and all tests pass. Also the test case in the first comment prints the timers in order. jBarz@e93c751
Activity
petkaantonov commentedon Mar 26, 2015
FWIW:
Fishrock123 commentedon Mar 26, 2015
It still points to larger problems within the timers impl though.
petkaantonov commentedon Mar 26, 2015
Yes I definitely think that timers should guarantee order to the extent that browsers do, currently they don't do that even in normal code (normal as in not using domains) and code that assumes e.g.
setTimeout(..., 5)fires beforesetTimeout(..., 1000).is broken in node but works fine in browsers.Fishrock123 commentedon Jul 24, 2015
I'm pretty sure this has something to do with the fact that after an error timers.js re-schedules to start processing again on the next tick, but doesn't actually stop processing presently: https://github.com/nodejs/io.js/blob/master/lib/timers.js#L100
This diff fixes the test, but causes other problems, so I'm confused.
if you're curious, here's the error log from
make test(8 errors): https://gist.github.com/Fishrock123/ad3e50ac7e4e76740c3eFishrock123 commentedon Jul 24, 2015
Also, is it possible this only happens when the list gets processed at a time when all 3 should fire in the same tick? (i.e. >2ms)
trevnorris commentedon Feb 8, 2016
Just to add to this confusion, here's a slight change to the test script:
I've gotten the output of:
and
jasnell commentedon Apr 19, 2016
@trevnorris @bnoordhuis ... running this against master currently, given about 100 runs each on @bnoordhuis' original and @trevnorris' revised version and I'm not seeing any variability in the ordering over timer events. Could this one have been fixed?
Fishrock123 commentedon Apr 19, 2016
Strange. I'll investigate soon.
jasnell commentedon Apr 19, 2016
btw, ran the tests on OSX in case it happens to matter. Have not tried the same tests against v5 or v4 yet.
Fishrock123 commentedon May 2, 2016
Looks like I can still reproduce, at about the same rate.
Make sure you use a command looper. Here's a modified test to accommodate that.
... shell scripts: (fish-shell & bash)
2 remaining items
Fishrock123 commentedon Sep 17, 2016
Just repo'd on OS X 10.10.5. @imyller did you try my test case on repeat?
Maybe we should just call this "one of those odd domain bugs", close the issue, and call it a day.
Or I could spend like a week debugging it but that is probably not a good use of my time.
imyller commentedon Sep 17, 2016
@Fishrock123 Yes, I just let it loop with shell while-do on OS X 10.11.6 and couldn't reproduce.
With Linux test environment this is very easy to reproduce with only few repeats.
Your call, but I personally wouldn't close the issue yet because the reproduceable problem still exists and the cause is not yet understood.
Fishrock123 commentedon Sep 17, 2016
I suppose. I suspect unless someone else throws a considerable amount of time at it, this will just go away when domains are likely removed in a couple years.
I'm able to help with the timers side of things if anyone wants to take a look into it.
Maybe @misterdjules would actually be the best to take a look?
jBarz commentedon Dec 29, 2016
I took a crack at this and hopefully what I found is useful :-)
The callbacks are stored in an associative array that is indexed by the number of milliseconds.
So list[1] is created for 1ms callbacks, and list[2] is created for 2ms callbacks.
Both these lists are in the queue for the current tick.
When list[1] encounters an unhandled exception, only the 1ms list is postponed to the next tick.
However, list[2] still exists on the current tick and will go through.
The solution seems to be skip all further list[x] to the next tick.
I tested this on linux and all tests pass. Also the test case in the first comment prints the timers in order.
jBarz@e93c751
gibfahn commentedon Dec 29, 2016
@jBarz that sounds reasonable, could you submit a PR?
Fishrock123 commentedon Dec 29, 2016
Hmmmm that does actually make sense now that I think about it.
jBarz commentedon Dec 29, 2016
I added @Fishrock123 's test case from #1271 (comment)
Without the looping though. So it runs only once.
Fishrock123 commentedon Feb 15, 2017
Fixed by 9dac165
timer,domain: maintain order of timer callbacks
timer,domain: maintain order of timer callbacks
timer,domain: maintain order of timer callbacks
timer,domain: maintain order of timer callbacks
timer,domain: maintain order of timer callbacks