因此,我使用ktor
,并希望通过ThreadLocal
在整个上下文中提供一些数据。我看到的是:
val dataThreadLocal = ThreadLocal<String>()
suspend fun fromOtherFunction() = "From other function -- ${dataThreadLocal.get()}"
routing {
get("/hello") {
// [1]
launch(this.coroutineContext + dataThreadLocal.asContextElement(value = "world")) {
val fromHere = async {
"ThreadLocal value: ${dataThreadLocal.get()}"
}
val fromThere = async {
fromOtherFunction()
}
call.respond(fromHere.await() + "," + fromThere.await())
}
}
}
我所做的是确保从父launch
(标记为[1])调用的所有函数都可以访问这种“作用域”数据。
然而,我的应用程序非常大,我希望这对路由处理的所有请求都有效,而不希望每个路由都需要这种 Package 。
真正伟大的是:
intercept(ApplicationCallPipeline.Features) {
launch(this.coroutineContext + dataThreadLocal.asContextElement(value = "world")) {
...
}
}
routing {
get("/hello") {
val threadLocalValue = dataThreadLocal.get()
...
这显然不起作用,因为intercept
中的协程作用域没有包含路由的协程作用域。
我相信在幕后发生的是,每个调用都是在父协同例程范围内启动的(类似于我们的“请求线程”)。有没有什么方法可以让我修改一下上下文呢?有没有一种方法可以告诉ApplicationEngine
到+
一个额外的上下文元素,每当这个新的协同例程上下文启动时?
1条答案
按热度按时间gmxoilav1#
您可以使用修改后的
ApplicationEngineEnvironment
来实现这一点。要访问它,您需要编写自己的EngineMain或类似的类。以下是Netty的修改版本:魔法就发生在这条线上:
你不必有一个名为
EngineMain
的类,为了简单起见,我只是复制粘贴(参见https://github.com/ktorio/ktor/blob/main/ktor-server/ktor-server-netty/jvm/src/io/ktor/server/netty/EngineMain.kt)。您可以只使用主功能并手动进行配置。