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

newSingleThreadContext on Native can't close until timeouts finish #3768

Closed
dkhalanskyjb opened this issue Jun 1, 2023 · 2 comments
Closed
Assignees
Labels

Comments

@dkhalanskyjb
Copy link
Collaborator

Reported in the Kotlin Slack originally.

Simplified reproducer:

    @Test
    fun timeoutAffectsClosing() = runBlocking {
        val disp: CloseableCoroutineDispatcher = newSingleThreadContext("my-test")
        val result = withContext(disp) {
            // Disabling the inner timeout will make it work correctly
            withTimeout(30.seconds) {
                "Hello"
            }
        }
        println(result) // Print "Hello"
        disp.close()
        println("Dispatcher closed: $disp") // takes 30 seconds to get here
    }
@dkhalanskyjb dkhalanskyjb self-assigned this Jun 1, 2023
dkhalanskyjb added a commit that referenced this issue Jun 1, 2023
Before the change, the Worker is not notified about its work being
cancelled, due to no API being present for that.
We work around the issue by checking every 100 milliseconds whether
cancellation happened.

Fixes #3768
@cmelchior
Copy link

A work-around seems to be to use newFixedThreadPool(1, "my-test") instead of newSingleThreadContext("my-test"). This is working on Coroutines 1.6.4 -> 1.7.1.

@cmelchior
Copy link

cmelchior commented Jun 1, 2023

After some more testing, it seems that the above fix hits another bug. Trying to use the closed dispatcher doesn't throw an IllegalStateException but rather seems to hang for the timeout that was defined (in another part of the code).

This problematic behavior only occurs on Coroutines 1.6.4. On 1.7.0 and 1.71 an IllegalStateException is correctly thrown immediately.

    @Test
    fun timeoutAffectsClosing() = runBlocking {
        val disp: CloseableCoroutineDispatcher = newSingleThreadContext("my-test")
        val result = withContext(disp) {
            // Disabling the inner timeout will make it work correctly
            withTimeout(30.seconds) {
                "Hello"
            }
        }
        println(result)
        disp.close()

        // Attempt to use the dispatcher result in the same timeout behaviour (i.e. needing to
        // wait 30 seconds for `kotlin.IllegalStateException: Worker is already terminated`
        // This is only a problem on Coroutines 1.6.4, and seems to be fixed in 1.7.0.
        withContext(disp) {
            // Do nothing
        }
        println("Done")
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants