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.