-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
timers: fix eventloop block #15072
timers: fix eventloop block #15072
Conversation
Can you provide (and include in this PR) a test that fails without this fix? |
I appreciate the review request but I don't really know what this change effects :) I agree that a test case would be helpful. |
Eeeh, okay, I think I got it, and this might make sense? Basically, the question is whether interval timers should block the event loop if they are 100 % busy beyond their set interval or not. Given that, as mentioned in the issue, this "worked" on Node 4.x, I'm inclined to say this is the right thing to do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but really should come with a test case. If you need anything for that, let us know :)
Ping @zhangzifa |
@BridgeAR test case added, sorry for late. |
clearInterval(t3); | ||
})); | ||
})).end(); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure why the server is included in the test. And if I am correct this could actually obfuscate what we really want to test if the server responds in below than 10 milliseconds.
Please remove it therefore and find a simpler test case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simpler test case updated.
@BridgeAR How about the simplified test case? :-) @Fishrock123 Any comments? Thanks. |
clearInterval(t1); | ||
clearInterval(t2); | ||
clearInterval(t3); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is somewhat better but I still do not understand why there is any need for a extra function call. It should be sufficient without the fs.stat
call. Just the plain set timeout is necessary as far as I can tell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make sure a different event is blocked. Per my local test, timer with different interval is not blocked.
@zhangzifa this PR is almost ready to land. Would you mind taking another look? :-) |
a2bf72a
to
4291de8
Compare
@BridgeAR I have just rebased the commits to simplify the commit log. Ready to land from my pov. |
}, 10); | ||
|
||
const t3 = setTimeout(() => { | ||
throw new Error('eventloop blocked!'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why throw here? If the intent is that this function should not be called, then using common.mustNotCall()
would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's better, updated as your suggestion.
common.busyLoop(15); | ||
}, 10); | ||
|
||
const t3 = setTimeout(common.mustNotCall('eventloop blocked!'), 100).unref(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit - the unref
should not be necessary as the timeout is cleared later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, updated again. :-)
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. Fixes: nodejs#15068
Failures in CI are unrelated. |
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: #15072 Fixes: #15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
Landed in e647c5d |
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: #15072 Fixes: #15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: nodejs/node#15072 Fixes: nodejs/node#15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: #15072 Fixes: #15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: #15072 Fixes: #15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: #15072 Fixes: #15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: nodejs/node#15072 Fixes: nodejs/node#15068 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: James M Snell <[email protected]>
When an interval takes as long or longer to run as its timeout setting and the roundtrip from rearm() to its deferal takes exactly 1ms, that interval can then block the event loop. This is an edge case of another recently fixed bug (which in itself was an edge case). Refs: nodejs#15072
When an interval takes as long or longer to run as its timeout setting and the roundtrip from rearm() to its deferal takes exactly 1ms, that interval can then block the event loop. This is an edge case of another recently fixed bug (which in itself was an edge case). PR-URL: #18486 Refs: #15072 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
When an interval takes as long or longer to run as its timeout setting and the roundtrip from rearm() to its deferal takes exactly 1ms, that interval can then block the event loop. This is an edge case of another recently fixed bug (which in itself was an edge case). PR-URL: nodejs#18486 Refs: nodejs#15072 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
When there are at least 2 timers set by setInterval whose callback
execution are longer than interval, the eventloop will be blocked.
This commit fix the above bug.
Fixes: #15068
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)