Prevent event loop starvation by always scheduled goroutines. #1079
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If there are two or more goroutines that are constantly interacting with
each other, they both will regularly give back control to the scheduler.
But if scheduler never yields to the JavaScript's event loop, events
like IO or timers will never have a chance to fire, and, for example,
time.Sleep()
will never return.We can't yield to the event loop after every goroutine switch, the
overhead of
setTimeout()
is ~1000x higher than the tight while-trueloop.
To amortize the overhead we will how yield if there's no scheduled
goroutine (old behavior), or if we spent more than 4ms executing the
code. In my benchmark, the cost of goroutine switch changed from
273ns/op to 341ns/op, which we can live with — most apps don't have such
tight loops anyway.
Fixes #1078.