actually have separate “polymorphic” keys. This seems to mean it’s possible to create a coroutine context with a dispatcher A and an interceptor B that wraps A, where if you ask it for the interceptor you will get B but if you ask specifically for the dispatcher you’ll get A.
Has anyone written a blog or anything about gotchas with combinations of this, or done it before and hit snags? I’m seeing some weird behavior in this situation when B tries to wrap a continuation and then ask the wrapped dispatcher to intercept.
👀 1
Zach Klippenstein (he/him) [MOD]
10/19/2022, 4:53 PM
So it seems like
advanceUntilIdle()
isn’t working with
runTest(UnconfinedTestDispatcher())
when the
ContinuationInterceptor
returns a
DispatchedContinuation
. This test fails:
Copy code
@Test
fun minimalRepro() {
runTest(UnconfinedTestDispatcher()) {
val parentInterceptor = coroutineContext[ContinuationInterceptor]!!
val wrappedInterceptor =
object : AbstractCoroutineContextElement(ContinuationInterceptor),
ContinuationInterceptor {
override fun <T> interceptContinuation(continuation: Continuation<T>) =
// Return continuation directly and the test passes
// (DispatchedContinuation vs Continuation).
parentInterceptor.interceptContinuation(continuation)
}
var entered = false
withContext(wrappedInterceptor) {
launch {
entered = true
}
// OR replace this with yield() and the test passes.
advanceUntilIdle()
assertTrue(entered)
}
}
}
Zach Klippenstein (he/him) [MOD]
10/19/2022, 4:58 PM
@Stephen Edwards@billjings can either of you explain this?