kotlinx.coroutines: Can't join a canceled task
Hi,
In the following code, I want to make sure my code blocks until the task is really finished:
val job = async(CommonPool) {
while (isActive);
Thread.sleep(1000)
System.out.println("end of async")
}
job.cancel()
job.join()
System.out.println("end of test")
The result is that I see “end of test” instantly, and “end of async” appears a second after, even though I asked to join() the task. Am I misusing the library or is this a bug?
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 2
- Comments: 21 (15 by maintainers)
I’ve pushed the corresponding changes to the
developbranch. Now jobs (includingDeferred) have an additional cancelling state. So, on invocation ofcancelthey go into cancelling state.isActivestarts returningfalse, butisCompleteis stillfalsein this state. Bothjoinandawaitwait for completion, that is they wait until the coroutine completes it execution.It is important to note, that in current implementation a cancelled coroutine is doomed to complete exceptionally. Even if
CancellationExceptionis caught inside a coroutine and is replaced with any kind of result, it will still go into cancelled state on completion.Note, that the naming of various states (see docs on
JobandDeferred) are still under consideration and may change: https://github.com/Kotlin/kotlinx.coroutines/blob/develop/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/Job.ktThe reason to change the implementation of
joinandawaitis two-fold. One is consistency withThread.joinas was mentioned above, but that would not be so compelling if not for the other. The other is to ensure thatasync(context) { doSomething() }.await()is really working just asrun(context) { doSomething() }without any spurious concurrency on cancellation. This is what really bothers me in the current (version <= 0.16) implementation ofjoinandawait, it is that when I cancel the coroutine, then the other coroutine that was waiting for it is going to be executed concurrently with whatever code that was still running in the coroutine that was cancelled, but has not completed just yet. This concurrency would be so rare, that it would be a source of very hard-to-diagnose bugs.Released in version 0.17
I plan to get it released soon (this or next week)