Skip to content
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

ThreadContextElement failure breaks cancellation #773

Closed
cy6erGn0m opened this issue Oct 30, 2018 · 1 comment
Closed

ThreadContextElement failure breaks cancellation #773

cy6erGn0m opened this issue Oct 30, 2018 · 1 comment
Assignees
Labels
design docs KDoc and API reference

Comments

@cy6erGn0m
Copy link
Contributor

cy6erGn0m commented Oct 30, 2018

An exception in updateThreadContext breaks job cancellation sequence so the following example hangs forever

package org.jetbrains.tests.cy.element.failure

import kotlinx.coroutines.*
import java.lang.IllegalStateException
import kotlin.coroutines.*

class MyElement : ThreadContextElement<Unit> {
    private object Key : CoroutineContext.Key<MyElement>

    override val key: CoroutineContext.Key<*> get() = Key

    override fun restoreThreadContext(context: CoroutineContext, oldState: Unit) {
    }

    override fun updateThreadContext(context: CoroutineContext) {
        throw IllegalStateException("Prevent a coroutine from starting right here for some reason")
    }
}

fun main() {
    runBlocking {
        GlobalScope.launch(MyElement()) {
            println("OK")
        }.join()
    }
}

I'd expect it to cancel job and resume join (since it is running not under MyElement so it is possible to resume it) however it remains Active

@qwwdfsad qwwdfsad self-assigned this Oct 31, 2018
@qwwdfsad qwwdfsad added docs KDoc and API reference design labels Oct 31, 2018
@qwwdfsad
Copy link
Collaborator

There is not much we can do.
We can't resume coroutine in a semi-updated context. If we can't resume it (and cancellation implies resume with exception), we can't complete it, so any join will hang.

All solutions may lead to unexpected behaviour:

  1. Resuming job in a semi-updated context breaks the contract of ThreadContextElement
  2. Transferring job to the final state breaks atomicity and cancellation contract
  3. Catching and reporting exceptions in every context element and then resuming coroutine will effectively disable "restore" and may leave context element in an inconsistent state.

qwwdfsad added a commit that referenced this issue Mar 7, 2019
…ption instead of rethrowing it to provide faster feedback loop

Fixes #808
Fixes #773
qwwdfsad added a commit that referenced this issue Mar 13, 2019
…ption instead of rethrowing it to provide faster feedback loop

Fixes #808
Fixes #773
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design docs KDoc and API reference
Projects
None yet
Development

No branches or pull requests

2 participants