Comfy Cats Effect room. Ask questions. Rant about config file formats. Be nice!
I share that opinion. But, I'm wondering if there are cases where you have a lot of flatmapped actions stacked up on each other in a gigantic IO program, and you know you would like to yield every once in a while, but it's hard to inject that into your code because it's not really clear where those points actually are.
That's the concern exactly. In practice I've found this is rare to the point of non-existent, but I imagine it could happen. The only times I've been bitten by lack of fairness, it was my own fault and relatively easy to fix. If you think about what has to happen for a long series of CPU-hogging code to avoid any async boundaries at all, it usually requires a ton of pure compute code (so, you're doing map
with some f
which is expensive but pure). In that case, it doesn't matter whether your semantics are auto-yielding or not: it's going to hog the thread.
For there to be code which can be more fairness-optimized by some mechanism in the effect type, but isn't already so optimized, you need a ton of delay
actions bound together with flatMap
s. A ton of them. Without any async
in between and without any shift
s to other pools. That… happens… very very very rarely.
Which is to say that auto-yielding isn't as helpful as it sounds in practice. Certainly still meaningful, but more meaningful on paper than in reality.
If I use Async.async() inside of Resource.use(), I need to ensure myself that somehow the async operation is completed prior to the resource's release method is called
The use
method will not be called until (at least!) the callback inside of async
is run. Which is to say, you have control over it. Remember that async
doesn't mean "parallel", it just means non-blocking.
R
. Within the use
method I use Async.async() on R
(so the callback necessarily has to be called after the use
method). Assuming I am not altering ExecutionContexts or ContextShifts, is it possible for the release
method to be called prior to the callback finishing if I do not explicitly synchronize this?
use
, not after
start
, then you have a problem
async
, you will be safe
async
you see it
A => Unit
foo = bar(a)
becomes bar(a, foo => everythingElse)
bar(a: A, logicalReturn: A => Unit) = ...., logicalReturn(result)