Ulrik Rasmussen
11/12/2021, 2:20 PMd
that I have obtained by calling .asCoroutineDispatcher()
on a single-threaded executor service. I want to launch long-running coroutines on this dispatcher from synchronous code. The obvious choice seems to be runBlocking(d) { launch { ... } }
, but that blocks the thread until the job launched by launch { }
completes. Can I submit a long-running job to d
from synchronous code without blocking the current thread?uli
11/12/2021, 2:40 PMval scope : CoroutineScope
class XXX {
val scop = CoroutineScope(SupervisorJob() + d)
fun launchJob() {
scope.launch { ... }
}
fun dispose() {
scope.cancel()
}
}
The CoroutineScope
will tell it’s coroutines, which dispatcher to use, how to handle exceptions and most noteably to cancel the potentially whole tree of child coroutines.
Disclaimer: Might not even compile.Ulrik Rasmussen
11/12/2021, 2:42 PMuli
11/12/2021, 2:43 PMUlrik Rasmussen
11/12/2021, 2:44 PMuli
11/12/2021, 2:44 PMUlrik Rasmussen
11/12/2021, 2:46 PMd
?Ulrik Rasmussen
11/12/2021, 2:46 PMSubervisorJob
is necessary because launch
will fail if there is no parent job in the scope?uli
11/12/2021, 2:48 PMcancel
on scope’s Job which will then cancel all it’s children. So if you do not set a job, cancelation aka structured concurrency will not work.Ulrik Rasmussen
11/12/2021, 2:48 PMUlrik Rasmussen
11/12/2021, 2:48 PMUlrik Rasmussen
11/15/2021, 7:22 AMd
with a custom serial dispatcher that just runs all its jobs on the current thread when a custom .run()
method is called on it. I am using coroutines to simulate nodes in a network that pass messages back and forth, and this allows me to make the simulation completely deterministic and allows the detection of deadlocks immediately without the use of timeouts.