-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
setInterval where callback "work" time is more then interval, will sleep for work time, not zero #5864
Comments
The current behavior is also what browsers do, right? Also ping @Fishrock123 for timers. |
No, most browsers schedule the repeat before handling the callback, like libuv does for instance: https://github.com/libuv/libuv/blob/v1.x/src/unix/timer.c#L165 that also prevents the interval from becoming effectively timeout + cputime. Wheras due to this bug, if all timers of timeout T have a total cpu time > T, and that is all you do, you get exactly 50% cpu usage, because nodejs is going to sleep for exactly total cpu time. |
Excellent! Indeed that is the same issue. I had used search, but the issues referenced are all already set to closed. Perhaps it is better to keep issues open until the pull request has landed? Or perhaps I should have search the pull requests as well? |
Good suggestion. I reopened #5426 to have one issue in nodejs/node that describes this problem. I still think we can close duplicate issues like this one as duplicate, as long as we mention what is the reference issue in their comments and we label them properly. Let me know if that works for you! |
@misterdjules Agree, keep one open, close duplicates. Thanks |
When setting
setInterval
with a relatively short interval, and a callback that (sometimes) takes longer on cpu then that short interval, will delay the next callback by time it was on cpu, not 0 or interval.Below is a testcase from what could be a gameloop that tries to do work every 100 millis exactly. When the simulated work is more then 1 millis, it will run into the problem above.
The scope of the bug is slightly more broad: any setInterval or setTimer with a certain timeout T, if we are currently processing timers of that T, and total processing of all timers of time T takes more time then T, the system will go into this state, where it will postpone for exactly CPU time. Resulting in a system that when under load uses exactly 50% cpu. Moreover, newly scheduled timers might get processed in the same loop, which violates the (perhaps implicit) contract that newly scheduled timers are only processed in the next io loop.
Related, this way of handling repeated timers means the actual interval is T + average cpu time of all timers of T.
a preliminary fix, but still a problem, the
this.start(0, 0)
, orthis.start(msec - diff, 0)
have no relation with the actual current time, andTimerWrap.now()
returns loop time, not wallclock time.The text was updated successfully, but these errors were encountered: