Add runtime flag to enable / disable execution shift deferring #8854
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.
Related issue: #8368
Context
The current behaviour of the ZIO runtime is to defer execution context shifting until an async operation takes place. There is a fair bit of debate around this behaviour, with valid arguments from both sides.
The good
Reducing execution context shifting can improve performance, especially in situations where we might be constantly shifting in-and-out of the execution context.
In the case below, execution context shifting deferral works well because after the first line is evaluated, we continue execution in the blocking threadpool, which means that when the 2nd
ZIO.succeedBlocking
occurs, we won't be shifting back execution.Another valid usecase is the one below, where execution context shifting allows us the same thread to execute the
_ + 1
computation, before it reaches the end of the async boundary.The bad
The most common use-case for shifting execution context is to perform blocking IO. In many cases, it is very likely to perform some/much CPU work to process the data obtained via IO. Since ZIO's blocking threadpool is unbounded, this means we could end up running CPU-bound workflows, which is.. very bad.
One example where this happens is in
zio-query
. What might not be immediately obvious in that code-block is thatdataSources
are almost definitely going to perform some IO, very often blocking IO. Following the execution of the datasource, we need to do some moderately expensive CPU such as creating HashMaps, fulfilling promises, etc.PR changes
Currently, the only way to disable this behaviour is to override the default executor. However, this is just a side effect rather than the intended behaviour, and that might change at some point in the future.
Instead of taking sides on this argument, I think a better approach is to give users the option to control this behaviour explicitly via a
RuntimeFlag
(enabled by default to maintain the same behaviour as before). This also unlocks the potential for power users to enable/disable this behaviour in specific regionsPS: Please provide some feedback/alternatives for the naming of the flag. I think we can do better!