than_
12/11/2020, 10:03 AMA PR was raised to make Arrow Fx Coroutines depend on KotlinX Coroutines to easy integration and usage since almost everyone has KotlinX Coroutines on the classpath anyway. More details in the PR Reviews and feedback welcome:Β https://github.com/arrow-kt/arrow-fx/pull/317I noticed a little discrepancy in deprecation of
ForkConnected
here it should be ReplaceWith("async(ctx) { f() }", "kotlinx.coroutines.Deferred")
The thing is, signature of async
is CoroutineScope.async(ctx...
. But ForkConnected
itself doesn't need CoroutineScope
. Was this intended, or is it an oversight?simon.vergauwen
12/11/2020, 11:07 AMForkConnected
since it violates the rules of structured concurrency.simon.vergauwen
12/11/2020, 11:08 AMparMapN
, parTraverse
etc
Is there a specific use-case you have in mind?simon.vergauwen
12/11/2020, 11:09 AMthan_
12/11/2020, 11:29 AMdispatch
is suspended, so everything here happens in scope of the caller, so cancellation seems to work fine, actually everything seems to work well π. But maybe my understanding of coroutines is incomplete and I'm just missing some problem.simon.vergauwen
12/11/2020, 1:29 PMGlobalScope.async { .. }
or CoroutineScope(ctx).async { }
or launch
.
You could also use coroutineScope
here if you want everything to be grouped together, but then logAction
would be able to fail dispatch
and the duration of dispatch
would be equal to the longest-running task here.
KotlinX Coroutines offers more variants on launching fibers which Arrow Fx offered, and also some more powerful ones for grouping lifecycles using coroutineScope
. if you have any code pushed somewhere, I'd be happy to help you migrate π Or answer any questions.than_
12/11/2020, 3:09 PMForkConnected
breaks structured concurrency π. Thanks for your time.simon.vergauwen
12/11/2020, 3:20 PMcoroutineScope {
async { delay(1000)
// <-- immediate return after fork
}
// Still takes 1000 since coroutineScope awaits async to finish
coroutineScope {
CoroutineScope(coroutineContext).async { delay(1000) }
// <-- immediate return after fork
} // Returns immediately as well since here async is launched on a seperate scope
ForkConnected
is like the second one in that it returns immediately from coroutineScope
but it still gets cancelled if it's parent scope gets cancelled.simon.vergauwen
12/11/2020, 3:21 PMsimon.vergauwen
12/11/2020, 3:22 PMthan_
12/11/2020, 3:53 PMForkConnected
is basically
inline fun <T> ForkConnected(
ctx: CoroutineContext = ComputationPool,
crossinline f: suspend () -> T,
): Deferred<T> =
CoroutineScope(ctx).async { f() }
makes migrations easy π
Tought I knew how structured concurrency works. But why this gets correctly cancelled, I have no idea πsimon.vergauwen
12/11/2020, 3:59 PMinline suspend fun <T> ForkConnected(
ctx: CoroutineContext = ComputationPool,
crossinline f: suspend () -> T,
): Deferred<T> =
CoroutineScope(coroutineContext).async(ctx) { f() }
It's like this actually, and it gets cancelled if coroutineContext
contains a Job
this Deferred
will have the same Job
attached and cancelling it will also cancel this Deferred
.than_
12/11/2020, 4:28 PMsimon.vergauwen
12/12/2020, 9:55 AMInt
version!
I created a ticket for it if you're up for it! π
https://github.com/arrow-kt/arrow-fx/issues/324