修改ktors调用协同例程上下文

时间:2019-05-06 11:17:01

标签: kotlin kotlin-coroutines

所以我正在使用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告诉+一个附加上下文元素?

0 个答案:

没有答案