obobo
04/11/2019, 4:35 PMDominaezzz
04/11/2019, 4:40 PMobobo
04/11/2019, 4:41 PMobobo
04/11/2019, 4:45 PMcoroutineContext
says that it inherits the parent's context, but overrides the parent's `Job`; I want to make sure that that means that the SupervisorJob
is overriden.bdawg.io
04/11/2019, 4:49 PMobobo
04/11/2019, 4:49 PMDominaezzz
04/11/2019, 4:56 PMC
, then B
still gets cancelled?!obobo
04/11/2019, 4:58 PMThis function is designed for a parallel decomposition of work. When any child coroutine in this scope fails, this scope fails and all the rest of the children are cancelled (for a different behavior see supervisorScope).
From the docs for coroutineScope {}
Dominaezzz
04/11/2019, 5:00 PMobobo
04/11/2019, 5:13 PMDominaezzz
04/11/2019, 5:27 PMDominaezzz
04/11/2019, 5:28 PMbdawg.io
04/11/2019, 5:35 PMasync {
try {
error("oops")
} catch (err: Throwable) {
//Exception caught, async coroutine does not complete exceptionally
}
}
bdawg.io
04/11/2019, 5:38 PMcoroutineScope { }
is launching a child coroutine of your SupervisorJob
bdawg.io
04/11/2019, 5:42 PMsupervisorScope { }
instead of with(CoroutineScope(coroutineContext + SupervisorJob())) { }
obobo
04/11/2019, 5:43 PMobobo
04/11/2019, 5:47 PMsupervisorScope {}
I can't use a specific dispatcher, while I can if I use the CoroutineScope
factory function.Dominaezzz
04/11/2019, 5:52 PMsupervisorScope
.Dominaezzz
04/11/2019, 5:56 PMobobo
04/11/2019, 6:34 PMbdawg.io
04/11/2019, 8:53 PMbdawg.io
04/11/2019, 8:55 PMsupervisorJob { }
suspends until all its child jobs have completed, ensuring that you do not leak running jobs. By doing with(CoroutineScope(coroutineContext + SupervisorJob())) { ... }
, you are breaking the hierarchy with a job that has no parent. This is the reason coroutineScope { }
exists and behaves the exact same way, but with a normal Job instead of SupervisorJob.
If you want to modify the dispatcher, you should set the context using withContext()
instead
supervisorJob {
withContext(<http://Dispatcher.IO|Dispatcher.IO>) {
...
}
} // waits until all children jobs are completed
with(CoroutineScope(coroutineContext + <http://Dispatchers.IO|Dispatchers.IO> + SupervisorJob())) {
...
} // does not wait for children jobs to complete - also the jobs launched inside this block are not tracked to a parent job, breaking structured concurrency
obobo
04/11/2019, 8:58 PMSupervisorJob()
. In previous discussions creating a scope that way was actually the recommended solution.obobo
04/11/2019, 9:03 PMobobo
04/11/2019, 9:06 PMbdawg.io
04/12/2019, 3:18 PMsupervisorScope { }
instead of a factory method that's blindly overwriting the job the context is tracked to.
If my original comments weren't helpful, hopefully you received the answer you were looking for 👍
SupervisorJob will not cancel due to a child [coroutine] completing exceptionally
is launching a child coroutine of yourcoroutineScope { }
SupervisorJob