-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Hi Kotlin team,
IIUC, each coroutine should have a dedicated CopyableThreadContextElement, and use this element to call updateThreadContext and restoreThreadContext at the beginning and end of each sub-routine, respectively. However, we found that is not always the case, and here is an example: https://pl.kotl.in/USpmRjCNL.
The following details my observation of the code's execution:
val flow =
flow {
// 1. Here updateThreadContext is called on
// TestElement("flowOn")'s child (the distinction is "flowOn" v.s. "collect", where child is immaterial,
// so will skip mentioning child in the following explanation)
log("before emit")
// 2. We call the block in collect below, and suspend
emit(1)
// 4. As we reach here, TestElement("flowOn").updateThreadContext is not called
// although the current context is (has, but use "is" for the simplicity of explanation) TestElement("flowOn")
log("after emit")
}
.flowOn(TestElement("flowOn", null))
launch(TestElement("collect", null)) {
flow.collect {
reached.set(true)
log("collect about to lock")
mutex.lock()
// 3. When resuming, updateThreadContext is called on TestElement("collect")
log("collect resumed")
}
}Here is the highlighted output to show so:
[13] updateThreadContext: TestElement(name=child[0], parent=TestElement(name=collect, parent=null))
[13] collect resumed
// <- no updateThreadContext for TestElement("flowOn")
[13] after emit
[13] restoreThreadContext: TestElement(name=child[0], parent=TestElement(name=collect, parent=null))For context we have a ThreadLocal-based tracing system, which supports coroutine tracing with the help of CopyableThreadContextElement, and we have clients broken by this because the correct trace is not restored (for the missing updateThreadContext call). So post the finding here and see if we can get this fixed, thanks!