-
Notifications
You must be signed in to change notification settings - Fork 0
Don't block the event loop on context end and related fixes #9
Conversation
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.
It's good to create a test for it, but keeping I guess urgency it could be a separated PR 👍
92cb8b7
to
6fdef09
Compare
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
6fdef09
to
6981438
Compare
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 | ||
} |
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 the original fix
(async () => { | ||
let poll = async (resolve, reject) => { | ||
await (async () => 5); | ||
setTimeout(poll, 1, resolve, reject); | ||
interrupt(); | ||
} | ||
setTimeout(async () => { | ||
await new Promise(poll) | ||
}, 0) | ||
})() | ||
`) |
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.
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.
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.
🚀
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