所以我正在使用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])调用的所有函数都可以访问这种“范围”数据。
但是,我的应用程序很大,我希望它能处理路由处理的所有请求,而不希望每个路由都需要这种包装。
真正伟大的是:
intercept(ApplicationCallPipeline.Features) {
launch(this.coroutineContext + dataThreadLocal.asContextElement(value = "world")) {
...
}
}
routing {
get("/hello") {
val threadLocalValue = dataThreadLocal.get()
...
这显然是行不通的,因为intercept
中的协程范围没有将路线的协程范围括起来。
我相信在幕后发生的是,每个调用都是在父协同例程范围内启动的(类似于我们拥有“请求线程”的方式)。我有办法修改其中的上下文吗?每当启动这个新的协同例程上下文时,是否可以让ApplicationEngine
告诉+
一个附加上下文元素?