Hi folks. Is there any reason `launch`ing a new co...
# coroutines
k
Hi folks. Is there any reason `launch`ing a new coroutine in a cancelled scope doesn’t error at all, and instead fails silently?
s
Maybe for the same reason (what ever that reason is) that Coroutines created (but not yet started/dispatched) while inside an active CoroutineScope will silently go away when they finally are about to get started/dispatched at the time the CoroutineScope is inactive.
j
Launching a coroutine right before or right after the scope is cancelled should not behave differently IMO. Throwing an exception when launching a coroutine in a cancelled scope would create an artificial difference that is not desirable. Imagine if you had to deal with races between launches and scope cancellation to handle this difference!
☝️ 2
k
We’re already having to deal with races when our scope is cancelled, except now we’re chasing a silent bug instead of one that crashes.
j
We’re already having to deal with races when our scope is cancelled
In which way?
k
We share viewmodels between iOS and Android. Right now, they have a lifecycle associated with them. This is something I would like to remove in the future, and make them stateless. However, we currently have to rectify lifecycle difference per platform with a common API. Our iOS viewmodels are cancelling their scope at different times than our Android ones. Therefore, certain code paths try to
launch
something, and it fails silently. This is a problem only in native for us. I realize this problem ultimately stems from our poor viewmodel arch. However, it made this bug difficult to track down because there was no indication that the coroutinescope was defunct. Instead, the
block
to launch would never get invoked.
j
Job.join()
on a job that's part of a structured hierarchy at the root of which is a cancelled scope is not silent. It will throw an exception, if you need that as a signal.
a
It does not: https://pl.kotl.in/K4vWokfsY
join
returns when all children have joined, it does not throw an exception if parts of the job hierarchy have failed
cancellation means, "stop and clean up" - if a coroutine never started running before it was cancelled it has nothing to clean up (e.g.
finally
blocks to run as the
CancellationException
tears it down)
j
@Adam Powell It throws here. And from the docs on `join`:
This suspending function is cancellable and always checks for a cancellation of the invoking coroutine's Job. If the Job of the invoking coroutine is cancelled or completed when this suspending function is invoked or while it is suspended, this function throws CancellationException.
j
I don't think cancellation exception counts in the eyes of the original question. It's just how cancellation works.
a
yes, if the caller of
join
is cancelled then
join
will throw the accompanying
CancellationException
- that's standard cancellation on the caller's side. It's not dependent on the job being joined though
`launch`ing a new coroutine in a cancelled scope doesn't produce an error for the same reason that
Copy code
val job = launch { ... }
job.cancel()
doesn't produce an error either