Could someone please explain why do I see the `out...
# coroutines
n
Could someone please explain why do I see the
outerScope END
log in this example? https://pl.kotl.in/BMb6dLHG- It creates an outerScope, jumps on innerScope using
withContext
, then cancels outerScope while it’s running. Docs say:
Note that the result of
withContext
invocation is dispatched into the original context in a cancellable way with a prompt cancellation guarantee, which means that if the original coroutineContext in which
withContext
was invoked is cancelled by the time its dispatcher starts to execute the code, it discards the result of
withContext
and throws CancellationException.
So I would expect
withContext
to, basically, throw before returning.
s
By passing a custom context (containing a custom Job) to
withContext
, you’re basically making it ignore cancellation of the outer scope. The behaviour is the same as if you wrote
withContext(NonCancellable)
.
n
Yes, I understand why it won’t cancel while running (
innerScope END
line). But docs say it should throw before returning, after switching back to the outer context.
s
In this case I think the key might be that the two contexts share the same dispatcher. There’s a note at the end of the docs:
The cancellation behaviour described above is enabled if and only if the dispatcher is being changed. For example, when using withContext(NonCancellable) { ... } there is no change in dispatcher and this call will not be cancelled neither on entry to the block inside withContext nor on exit from it.
I’m not 100% sure on that though. But I did notice that if you do change the dispatcher, it doesn’t print the
outerScope END
message.
n
Ahh, that has to be the cause. Thanks a lot Sam. Not sure how I missed that note.
s
It seems like an odd design choice 😞. Strange for the choice of dispatcher to affect the cancellation checks.
c
It's a performance optimization. If the dispatcher is the same, withContext does almost nothing: https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/common/src/Builders.common.kt#L149
n
I too wish there was an ensureActive call when exiting.
c
I wonder why they didn't add one. Maybe this could be worth creating an issue to ask them to explain?
n
Maybe it’s because most people will not pass a different Job to
withContext
, so the contents of withContext can already react to cancellation. But if job is different it would be nice to have one for consistency