Skip to content
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

Closed
wants to merge 1 commit into from
Closed

Conversation

zhangzifa
Copy link
Contributor

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), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

@nodejs-github-bot nodejs-github-bot added the timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout. label Aug 29, 2017
@jasnell
Copy link
Member

jasnell commented Aug 29, 2017

Can you provide (and include in this PR) a test that fails without this fix?

@addaleax
Copy link
Member

I appreciate the review request but I don't really know what this change effects :) I agree that a test case would be helpful.

@addaleax
Copy link
Member

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.

Copy link
Member

@addaleax addaleax left a 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 :)

@BridgeAR
Copy link
Member

BridgeAR commented Sep 8, 2017

Ping @zhangzifa

@zhangzifa
Copy link
Contributor Author

@BridgeAR test case added, sorry for late.

clearInterval(t3);
}));
})).end();
}));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simpler test case updated.

@zhangzifa
Copy link
Contributor Author

@BridgeAR How about the simplified test case? :-)

@Fishrock123 Any comments? Thanks.

clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
});
Copy link
Member

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.

Copy link
Contributor Author

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.

@BridgeAR
Copy link
Member

@zhangzifa this PR is almost ready to land. Would you mind taking another look? :-)

@zhangzifa
Copy link
Contributor Author

@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!');
Copy link
Member

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.

Copy link
Contributor Author

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();
Copy link
Member

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.

Copy link
Contributor Author

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
@lance
Copy link
Member

lance commented Oct 16, 2017

@jasnell
Copy link
Member

jasnell commented Oct 18, 2017

Failures in CI are unrelated.

jasnell pushed a commit that referenced this pull request Oct 18, 2017
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]>
@jasnell
Copy link
Member

jasnell commented Oct 18, 2017

Landed in e647c5d

MylesBorins pushed a commit that referenced this pull request Oct 23, 2017
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]>
addaleax pushed a commit to ayojs/ayo that referenced this pull request Oct 26, 2017
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]>
MylesBorins pushed a commit that referenced this pull request Nov 16, 2017
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]>
@MylesBorins MylesBorins mentioned this pull request Nov 21, 2017
MylesBorins pushed a commit that referenced this pull request Nov 21, 2017
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]>
MylesBorins pushed a commit that referenced this pull request Nov 28, 2017
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]>
addaleax pushed a commit to ayojs/ayo that referenced this pull request Dec 7, 2017
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]>
apapirovski added a commit to apapirovski/node that referenced this pull request Feb 2, 2018
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
apapirovski added a commit that referenced this pull request Feb 4, 2018
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]>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

timers: eventloop is blocked when there are two or more callback duration is larger than interval
8 participants