Scope for "one-for-one" supervision (children don't crash parent and siblings)
See original GitHub issueThe default behavior of children coroutines in Kotlin loosely corresponds to “one-for-all” supervision behavior – when one crashed child kills all siblings (and parent, too). There is no automatic restart in Kotlin, but that is completely different topic. The default in Kotlin is chosen this way, because this is a good default for a use-case of parallel decomposition when one large job is decomposed it smaller jobs that work in parallel. It also makes coroutines ephemeral – a coroutine can always delegate a piece of its work to a child without an outside world noticing it.
However, sometimes, children coroutines are independend, but are still children in the sense that parent cancellation has to cancel them, too, however, their crash should not kill parent and all sibling coroutines, but shall be handled independently. Currently, it requires a bit of boilerplate to write:
launch { // child
try {
doSomething() // child's job
} catch(e: Throwable) {
// handle failure
}
}
In a particular project, the above boilerplate can be readily incapsulated into a function together with project-specific error-handling code:
fun CoroutineScope.launchAndHandle(suspend block: CoroutineScope.() -> Unit) {
launch { // child
try {
block()
} catch(e: Throwable) {
// handle failure
}
}
}
However, these kinds of functions cannot be readily provided by kotlinx.coroutines
, because they are not composable – one needs to define such function for each type of coroutine builder.
Instead, the proposal is to add a new CoroutineScope
builder function, so that one can write:
__independentCoroutineScope {
launch { // child
doSomething() // child's job
}
}
The __independentCoroutineScope
function (the good actual name is to be found) creates a CoroutineScope
of a special kind that makes all the coroutines launched directly from inside of it to have this special behavior – they are cancelled when the parent is cancelled, but their exceptions are handled independently by an installed CoroutineExceptionException
which can be inherited from a parent or can be specified in this builder explicitly:
__independentCoroutineScope(CoroutineExceptionHandler { .... }) {
launch { // child
doSomething() // child's job
}
}
Issue Analytics
- State:
- Created 5 years ago
- Reactions:6
- Comments:7 (5 by maintainers)
Top GitHub Comments
Tentative names are
supervisorScope { ... }
for a scope that would handle exceptions of its children independently andSupervisorJob()
for an explicit job object constructor with the same properties.@jcornaz We’ll use a special implementation of
Job
for that scope (one that does not cancel all children on a crash of one of them), so another way to expose this feature is to provide a separate__IsolatedJob()
constructor, in your example: