Yes but to be sure `Job() + Dispatchers.Main` crea...
# android
t
Yes but to be sure
Job() + Dispatchers.Main
create a new context and parent job? (The Android lifecycle part I master after all those years:p) and calling coroutineContext.Cancel() does cancel the parentJob and all the child + prevent new calls, and that coroutineContext.CancelChildren() only cancel running jobs for that context/job and allows queuing new ones?
l
Isn't
cancelChildren()
deprecated? BTW, you should use
SupervisorJob()
for the lifecycle bound scope.
t
only cancel and cancelchildren with cause param are deprecated and doc says to use the non cause version.
And I can't find any example or docs about using
SupervisorJob
for that purpose, only difference seems to be about exception moving up or not.
l
With a discussion about it
t
I've seen all the PR and updates of them, and just looked again you recently change to SupervisorJob but I can't see the reason behind it.
l
You may want to cancel one child coroutine without cancelling the whole root scope, because you may want to still be able to launch other coroutines
And for that, you need a
SupervisorJob
t
I'm lost documentation is all wrong so, for Job it's said
Copy code
Failure or cancellation of a child with an exception other than CancellationException immediately cancels its parent.
and from my tests it works.
I use the dispatched + job at root. to cancel all child I use context.cancelchidren. to cancel all I use context.cancel.
And to handle special jobs I store then from the launch or async and cancel that specific job.
This have never impacted the other jobs.
g
and from my tests it works.
Probably your tests are wrong or do not cover such case If one of coroutines in your scope with Job() throws exception parent scope and all child coroutines will be cancelled
2
t
Yes for exceptions but we are talking about cancelling here, at least this is what the doc said and what I tested, but @louiscad seemed to say that cancelling a child job in a job cancel the parent, this is what I'm talking about.
l
@Tolriq If you have an exception inside an
async
block that you catch at
await
time, the scope will still be cancelled unless it's a supervisor. That why supervisor is there, and that's why you should use it.
t
We are mixing things here: 1) Cancellation. From the doc cancellation of child jobs does not propagate to parent but only to it's child. This is what the doc says. Is this true or should I open an issue to have doc corrected? 2) Exceptions, can you point me to the doc that says that catching in async.await still cancel parent scope? From all example catching the await does prevent parent cancellation properly, supervisor is always describe as a way to only cancel childrens and not propagate to parent in case of unhandled exceptions. Maybe I'm missing something obvious but it's not visible in the basic docs.
l
See this issue: https://github.com/Kotlin/kotlinx.coroutines/issues/763 Do you think the documentation should be improved in this regard?
t
Well yes totally did not found that issue, and from https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/exception-handling.md#exception-handling it's really unclear that this happens at all. In my case for the moment I still catch exceptions inside the functions and not on await but planned to so really nice to know.
Can you still confirm that the cancellation thing is working as I currently heavily rely on it and was not able to spot any issues with that and went to public beta with that concept.
l
@Tolriq I'd advise you to test the behavior yourself in a test project or in a test branch of your current project, so you can see the exact behavior without taking my word for it. Regarding the docs unclarity, would you open an issue about it on GitHub?
t
I do believe you about async I just did not find anything about it in the docs and currently not using it. (I'll open an issue) The question is more about the cancellation, I did all the tests I could think of and had no issues at all. using dispatched.main + Job() then call 10 times a function that just does coroutinedispatcher.cancelchildren followed by launch properly start the launch block only once if switching thread and properly cancel the tasks (isActive false) when not fast enough or no swithing thread. And no issue to queue more coroutines. (Did tons of other tests, but this one should trigger the issue you are saying about cancellation.
l
I think it only happens on failure of a child scope, so you don't get any error if you cancel a scope normally with
cancel()
, and of course, there's no way
cancelChildren()
should cancel the parent too.
t
Ok so it's safe to use cancellation with jobs, it's just exception handling with async that would require supervisor to avoid scope issues. Thanks for the details.