There doesn't seem to be a way to provide a new Co...
# ktor
c
There doesn't seem to be a way to provide a new CoroutineContext for a Call, i.e. this doesn't work:
Copy code
//fun Application.installContextCaching() {
//    intercept(ApplicationCallPipeline.Plugins) {
//        withContextCache {
//            proceedWith(subject)
//        }
//    }
//}
Seems the pipelining don't wrap interceptors which is what is normally expected.?
m
creating a plugin works
Copy code
val yourPlugin = createRouteScopedPlugin(
    name = "Plugin",
    createConfiguration = { Config() }) {
    on(RequestContextRouteHook) { call, proceed ->
        withContext(...) { proceed() }
    }
}
c
Mmmm, I'll try the "createRouteScopedPLugin" then, the intercept didn't work unfortunatly
Yeah same issue
I did install to the application not that route tho, guessing thats the only difference can try that quickly
Yeah no bueno, it looks like it used to work in 2.x but not 3.x
m
I am pretty sure it works because I am using it extensively to pass the calling user, your problem must be somewhere else
c
Do you have a full example you can share?
a
The following code doesn't work as expected with both Ktor 2.3.13 and 3.2.1:
Copy code
fun main() {
    embeddedServer(Netty, port = 3333) {
        routing {
            withRequestContextCache {
                get {
                    println(coroutineContext[MyContextElement])
                    call.respondText { "OK" }
                }
            }
        }
    }.start(wait = true)
}

fun Route.withRequestContextCache(
    build: Route.() -> Unit
): Route {
    val route = this
    route.install(ContextCache)
    route.build()
    return route
}

val ContextCache = createRouteScopedPlugin(
    name = "ContextCache",
    createConfiguration = {}) {
    on(RequestContextCacheRouteHook) { call, proceed ->
        withContext(MyContextElement()) {
            proceed()
        }
    }
}
internal object RequestContextCacheRouteHook : Hook<suspend (ApplicationCall, suspend () -> Unit) -> Unit> {
    internal val RequestContextCachePhase: PipelinePhase = PipelinePhase("RequestContextCachePhase")
    override fun install(
        pipeline: ApplicationCallPipeline,
        handler: suspend (ApplicationCall, suspend () -> Unit) -> Unit,
    ) {
        pipeline.insertPhaseAfter(ApplicationCallPipeline.Plugins, RequestContextCachePhase)
        pipeline.intercept(RequestContextCachePhase) {
            handler(call, ::proceed)
        }
    }
}

class MyContextElement() : CoroutineContext.Element {
    override val key: CoroutineContext.Key<*>
        get() = MyContextElement

    companion object : CoroutineContext.Key<MyContextElement>
}
c
I have what @Aleksei Tirman [JB] has, so @minivac interest to see what you have that works...?