Closed
Description
Currently, CoroutineContext could be customized with AbstractCoroutineServerImpl
constructor.
And it is combined with GrpcContextElement
that captures a context from the current thread and propagates it.
However, a CoroutinContext
injected by users could not propagate any context from the current thread, because it was instantiated when the Coroutine stub is created.
We can use a hack that was suggested by @anuraaga, line/armeria#2669 (comment)
internal object ArmeriaContext: CoroutineContext {
override fun <R> fold(initial: R, operation: (R, CoroutineContext.Element) -> R): R =
EmptyCoroutineContext.fold(initial, operation)
override fun <E : CoroutineContext.Element> get(key: CoroutineContext.Key<E>): E? =
EmptyCoroutineContext.get(key)
override fun minusKey(key: CoroutineContext.Key<*>): CoroutineContext =
EmptyCoroutineContext.minusKey(key)
override fun plus(context: CoroutineContext): CoroutineContext {
val requestCtx: RequestContext = RequestContext.current()
return requestCtx.contextAwareExecutor().asCoroutineDispatcher() + context
}
}
We don't think this is a nice approach. If AbstractCoroutineServerImpl
get CoroutineContext
from a method then constructor parameter, gRPC-Kotlin users can easily propagate their context to CoroutineContext.
abstract class AbstractCoroutineServerImpl(
val defaultContext: CoroutineContext = EmptyCoroutineContext
) : BindableService {
open fun context(): CoroutineContext = defaultContext
}
class UserService: XXXCoroutineImplBase() {
override fun context(): CoroutineContext {
return ServiceRequestContext.current().contextAwareExecutor().asCoroutineDispatcher()
}
}
Do you think this change makes sense, I could make a PR. 😀
/cc @anuraaga
Metadata
Metadata
Assignees
Labels
No labels