https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

Sam

04/08/2019, 10:01 PM
Why does launch builder always adds Job to the new scope even when the current scope (used to launch a coroutine) uses a SupervisorJob?
g

gildor

04/08/2019, 11:32 PM
Because launch has own lifecycle and own scope for child coroutines which attached to parent, you can cancel this launch using Job that you received on launch start
s

Sam

04/09/2019, 12:05 AM
Yeah, i meant why not use a new SupervisorJob when the parent scope is associated with one
Copy code
val scope = CoroutineScope( Dispatchers.Default + SupervisorJob() )

    with(scope) {

        launch {

            launch {
                delay(500)
                throw Exception()
            }

            launch {
                try {
                    delay(1000)
                    println("launch sibling")
                } catch (e: CancellationException) {
                    println("sibling launch cancel")
                }
            }

            delay(1000)
            println("launch parent")
        }
    }
outer launch uses SupervisorJob where as the nested ones uses Job. So when the nested ones fail, it defeats the point of SupervisorJob
In case of android, viewModelScope has SupervisorJob and in some cases could end up with nested coroutines
g

gildor

04/09/2019, 1:38 AM
Yes, this is correct behavior
s

Sam

04/09/2019, 1:39 AM
Is there a way to enforce supervisor behavior across all nested levels?
g

gildor

04/09/2019, 1:39 AM
yes, start each of them in with own SupervisorJob
but I wouldn’t recommend it
this code is just not how real life code should look like
s

Sam

04/09/2019, 1:41 AM
Okay, i tried launch( SupervisorJob() ) but that defeats structured concurrency (parent-child relation is lost)
g

gildor

04/09/2019, 1:41 AM
yes, sure
you have to use supervisorScope builder
but It would look strange and it is by design, because it’s against recommended way to work with coroutines
s

Sam

04/09/2019, 1:42 AM
It seems like if launch was designed to user Job/SupervisorJob based on the one in the scope, it would work just fine right?
g

gildor

04/09/2019, 1:42 AM
Not sure that I understand question
s

Sam

04/09/2019, 1:43 AM
If a coroutine is launched in a scope associated with SupervisorJob , then launched coroutine's child job too could have been a SupervisorJob.
g

gildor

04/09/2019, 1:43 AM
What kind behavior do you expect?
s

Sam

04/09/2019, 1:43 AM
This would have taken care of parent-child relation as well
g

gildor

04/09/2019, 1:44 AM
then launched coroutine’s child job too could have been a SupervisorJob.
No! And it by desgin
s

Sam

04/09/2019, 1:45 AM
I'm trying to understand the rationale behind that design. Any reason not to use SupervisorJob?
g

gildor

04/09/2019, 1:45 AM
Because SupervisorJob is less safe and more error prone, you should take care on all exceptions and handle lifecycle of other coroutines
First what you should ask yourself “Why do you need SupervisorJob behavior”
s

Sam

04/09/2019, 1:46 AM
Unidirectional cancel behavior irrespective of nested level of coroutines
g

gildor

04/09/2019, 1:47 AM
it’s fine for some component with scope (like ViewModel) to run multiple coroutines and handle excceptions manually, you don’t want to cancel scope of this component, but on other levels it doesn’t needed in most cases and you just avoid running all those nested coroutines with
launch
s

Sam

04/09/2019, 1:47 AM
I don't have a real application case though, just playing with it
g

gildor

04/09/2019, 1:47 AM
a real application case though
Do you have at least some problem what you trying to solve in sample?
s

Sam

04/09/2019, 1:48 AM
Nothing more than the code i shared.
Will keep an eye on this, if i ever run into nested needs
g

gildor

04/09/2019, 1:49 AM
Nesting is fine, I just don’t see problem with this code
in terms of error handling
isn’t this what your tried to achieve in your first message in another thread: https://pl.kotl.in/S1j09dtYV
If you want to handle exception for each launch, no need to use CoroutineExceptionHandler, just use try/catch inside of launch
s

Sam

04/09/2019, 1:54 AM
Not really. The other thread was just to figure out why the handler was ignored (no parent-child relation)
g

gildor

04/09/2019, 1:55 AM
The other thread?
g

gildor

04/09/2019, 1:56 AM
ahh
Yes, but with SupervisorJob handler is not ignored anymore
so you can handle any uncaught exception on level of your ViewModel
but for asyncronous jobs, like in this sample, I just don’t see any reason to use SupervisorJob or CoroutineExceptionHandler
s

Sam

04/09/2019, 1:58 AM
Okay
4 Views