Affects: spring-webflux 5.3.7

I write my filter, pass some parameters to coroutine context via witchContext and want to be able use it later in the child coroutines and handlers. The problem is that CoroutineContext is lost in filter chain.

For example something like this

    @Bean
    fun testRouter(tracingFilter: ITracingFilter) = coRouter {
        GET("/test") { request ->
            val span = coroutineContext[SpanContext] //  is null
            someHandler.processRequest()
        }
        filter{ serverRequest, suspendFunction ->
            withContext(SpanContext()) {
                suspendFunction.invoke(serverRequest)
            }
        }
    }

Comment From: emrearslan

Is there any progress on this?

Comment From: sdeleuze

I can confirm the issue which seems to impact CoWebFilter as well on annotation-based programming model side cc @poutsma .

During filter + handler Coroutines use case, the handler should reuse the context defined by the filter and currently, it overrides it with Dispatchers.Unconfined when invoking the mono(Dispatchers.Unconfined) { } lambda at handler level. Using mono(Dispatchers.Unconfined) is ok when this is the "top level Coroutines invokation", but not when this is a handler 'nested' in a filter.

I guess the handler should reuse filter CoroutineContext when defined, but not sure yet how.

Comment From: sdeleuze

See potentially related issue #27522.

Comment From: sdeleuze

Looks like I have found a way to propagate correctly the CoroutineContext by introducing a HandlerFunction implementation that allows to pass explicitly the context:

abstract class ContextAwareHandlerFunction<T : ServerResponse> : HandlerFunction<T> {
    override fun handle(request: ServerRequest): Mono<T> {
        return handle(Dispatchers.Unconfined, request)
    }
    abstract fun handle(context: CoroutineContext, request: ServerRequest): Mono<T>
}

More details in this draft commit, feedback welcome.

Comment From: IevgenBizz

Hello @sdeleuze Thanks for your changes. I have related question: In our application we are using webflux and our controllers annotated with @GetMapping annotation. If I'm right you changes won't be applied for this case. There are used org.springframework.web.reactive.result.method.InvocableHandlerMethod#invoke

if (isSuspendingFunction) {
    value = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
}
else {
    value = method.invoke(getBean(), args);
}

Do you have any ideas how I can pass MDCContext() to suspended controller function, when MDC was set in CoWebFilter? (I found related thread https://github.com/spring-projects/spring-framework/issues/27522)

Comment From: sdeleuze

With Spring Boot 3.2 + Spring Framework 6.1, I think that should be the case, if not please create an issue with a minimal reproducer as an attached project or a link to a repository.