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