-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scope for "one-for-one" supervision (children don't crash parent and siblings) #576
Comments
Hmmm. Naming things is hard. |
@elizarov Do you think it would make sense to be able to configure it as the default of a given Like this for instance: class MyUiComponent : CoroutineScope {
override val coroutineContext = Job() + Dispatchers.UI
override val isolatedChidren = true // this may be `false` by default if not overriden
fun handleAction() {
launch { /* this coroutine is a child which won't crash the parent in case of failure */ }
}
} Or maybe as a context element: The motivation I have are UI components for which I want all children to be isolated. That way they will be cancelled at the end of the life of the component, but the component won't crash just because of an unexpected failure in an action. So I'd like to be able to specify that some given scopes launch children isolated by default. |
@jcornaz We'll use a special implementation of
|
Tentative implementation and name, no docs yet Fixes #576
Tentative names are |
Is it correct that another way to think about this is: a regular scope (non-supervisor) is effectively just a supervisor scope that cancels/fails itself on child failure? |
Tentative implementation and name, no docs yet Fixes #576
Tentative implementation and name, no docs yet Fixes #576
Nope. With supervisor, all children handle their exceptions independently (either via |
Documentation for Job spells the difference between the regular job and the supervisor job. Fixes #576
Good. Structured concurrency is the supervision tree :-). There is a example code for switching AllForOneStrategy or OneForOneStrategy : // here use argument reference ::coroutineContext if most people think :: is too easy to abuse, we could denote longer modifiers here, such as by field : |
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
This change also fixes propagation of cancellation for Job() constructor. When both Job() and SupervisorJob() are cancelled with exception (fail), they cancel their parent, too. So we have similar behavior between: * Job() and coroutineScope { ... } * SupervisorJob() and supervisorScope { ... } Fixes #576
The 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:
In a particular project, the above boilerplate can be readily incapsulated into a function together with project-specific error-handling code:
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:The
__independentCoroutineScope
function (the good actual name is to be found) creates aCoroutineScope
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 installedCoroutineExceptionException
which can be inherited from a parent or can be specified in this builder explicitly:The text was updated successfully, but these errors were encountered: