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

Don't block the event loop on context end and related fixes #9

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

mstoykov
Copy link
Collaborator

@mstoykov mstoykov commented Jan 11, 2024

Previously setTimeout (and co) might block the event loop in cases where
timeout hasn't triggered but the context has been done.

While fixing that some other potential races were found. Most of them
due to trying to write less code - but it is actually important that if
we are using the event loop we do all the stuff on it.

Additionally fixing a panic in init context if a timer gets interrupted -
all due to using the logger from the lib.State.

The test added did tease out a bunch of this issues, and does reproduce
the original issue on occasion. Unfortunately a better reproducible
test seems to be very hard to write

@mstoykov mstoykov requested a review from a team as a code owner January 11, 2024 17:32
@mstoykov mstoykov requested review from oleiade and olegbespalov and removed request for a team January 11, 2024 17:32
Copy link
Contributor

@olegbespalov olegbespalov left a comment

Choose a reason for hiding this comment

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

It's good to create a test for it, but keeping I guess urgency it could be a separated PR 👍

@mstoykov mstoykov changed the title Don't block the event loop on context end Don't block the event loop on context end and related fixes Jan 12, 2024
Previously setTimeout (and co) might block the event loop in cases where
timeout hasn't triggered but the context has been done.

While fixing that some other potential races were found. Most of them
due to trying to write less code - but it is actually important that if
we are using the event loop we do all the stuff on it.

Additionally fixing a panic in init context if a timer gets interrupted
- all due to using the logger from the lib.State.

The test added did tease out a bunch of this issues, and does reproduce
the original issue *on* occasion. Unfortunately a better reproducible
test seems to be very hard to write
Comment on lines +216 to +222
select {
case ch <- struct{}{}:
// wait for this to happen so we don't need to hit the event loop again
// instead this just closes the queue
<-ch
case <-e.vu.Context().Done(): // still shortcircuit if the context is done as we might block otherwise
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the original fix

Comment on lines +176 to +186
(async () => {
let poll = async (resolve, reject) => {
await (async () => 5);
setTimeout(poll, 1, resolve, reject);
interrupt();
}
setTimeout(async () => {
await new Promise(poll)
}, 0)
})()
`)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not certain which parts make more of a difference ... or less, but this is the smallest I got to actually reproduce the issue without needing the whole k6.

Copy link
Member

@oleiade oleiade left a comment

Choose a reason for hiding this comment

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

🚀

@mstoykov mstoykov merged commit 42a2334 into main Jan 12, 2024
10 checks passed
@mstoykov mstoykov deleted the unblockEventLoop branch January 12, 2024 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants