Gopal S Akshintala
08/21/2020, 1:00 PMparTraverse
uses fibers underneath, how can I see that effect apart from measuring time (like by printing Fiber-id or something). I tried this example:
@Test
fun `parTraverse + blocking`() {
val time = measureTimeMillis {
runBlocking {
(1..20).parTraverse {
blockingWork(it)
}
}
}
// 3s, multiple blocked bg threads
println("Done in $time ms [${Thread.currentThread().name}]")
}
simon.vergauwen
08/21/2020, 1:31 PMExecutorService
like you'd manually do from Java.
The only offer higher level abstractions so you don't have to deal with them manually.
Afaik "@coroutine#1" is being printed if you use dispatchers from KotlinX, but those are still eventually scheduled on the ForkJoinPool
like you see happening here.
We provide an IOPool
(which you should definitely use when using Thread.sleep
, since that blocks the thread). If you use that one you'll see arrow-effects-worker-x
being printed instead.simon.vergauwen
08/21/2020, 1:32 PMintercepted()
in combination with a dispatching ContinuationInterceptor
.simon.vergauwen
08/21/2020, 1:33 PMIO
in Arrow Fx or Cats effects in Scala, RxJava, Reactor etc. It hides the complexity of using Executors
directly, which offers a much more powerful and safe way to work with highly concurrent programs.Gopal S Akshintala
08/21/2020, 1:35 PMsimon.vergauwen
08/21/2020, 1:35 PMVirtualThread
everywhere instead of executors/pools. This would allow you to treat every thread as a blocking-capable thread (IOPool
) without paying any of the costs of doing so.
That open the door to some techniques that now would be considered too expensive, like looping on a thread to wait for a result. Or using Thread.sleep
to get better precision over ScheduledExecutorService
.