Kotor 2 - 如何为请求添加线程本地数据?
Ktor 2 - How to add thread local data for a request?
在 Ktor 2 之前,可以在 ApplicationFeature
中使用 withContext(threadLocal.asContextElement(..)) { proceed() }
将线程本地数据添加到请求中,但新的 createApplicationPlugin
api 不会似乎提供了这个选项。还有可能吗?这听起来像是一个很常见的用例...?
我认为我在 大量 挖掘 Ktors 源代码之后弄明白了。我认为 Ktor 2 中的新插件 api 是一个改进,但是用 ServletFilter 做一些 five-ish 行代码的事情仍然非常困难...
val ServerTracerPlugin = createApplicationPlugin(
name = "KtorServerTracerPlugin",
createConfiguration = ::KtorTracingPluginConfig
) {
on(TracerHook()) { call, block ->
// ...
withContext(threadLocalStorage.asContextElement(..)) {
block()
}
}
}
class TracerHook : Hook<suspend (ApplicationCall, suspend () -> Unit) -> Unit> {
override fun install(
pipeline: ApplicationCallPipeline,
handler: suspend (ApplicationCall, suspend () -> Unit) -> Unit
) {
val phase = ApplicationCallPipeline.Monitoring
val namedPhase = PipelinePhase("${phase.name}Trace")
pipeline.insertPhaseBefore(phase, namedPhase)
pipeline.intercept(namedPhase) {
handler(call, ::proceed)
}
}
}
在 Ktor 2 之前,可以在 ApplicationFeature
中使用 withContext(threadLocal.asContextElement(..)) { proceed() }
将线程本地数据添加到请求中,但新的 createApplicationPlugin
api 不会似乎提供了这个选项。还有可能吗?这听起来像是一个很常见的用例...?
我认为我在 大量 挖掘 Ktors 源代码之后弄明白了。我认为 Ktor 2 中的新插件 api 是一个改进,但是用 ServletFilter 做一些 five-ish 行代码的事情仍然非常困难...
val ServerTracerPlugin = createApplicationPlugin(
name = "KtorServerTracerPlugin",
createConfiguration = ::KtorTracingPluginConfig
) {
on(TracerHook()) { call, block ->
// ...
withContext(threadLocalStorage.asContextElement(..)) {
block()
}
}
}
class TracerHook : Hook<suspend (ApplicationCall, suspend () -> Unit) -> Unit> {
override fun install(
pipeline: ApplicationCallPipeline,
handler: suspend (ApplicationCall, suspend () -> Unit) -> Unit
) {
val phase = ApplicationCallPipeline.Monitoring
val namedPhase = PipelinePhase("${phase.name}Trace")
pipeline.insertPhaseBefore(phase, namedPhase)
pipeline.intercept(namedPhase) {
handler(call, ::proceed)
}
}
}