Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spring-webflux filters don't pass CoroutineContext #26977

Closed
Ghostleg opened this issue May 26, 2021 · 6 comments
Closed

spring-webflux filters don't pass CoroutineContext #26977

Ghostleg opened this issue May 26, 2021 · 6 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: enhancement A general enhancement
Milestone

Comments

@Ghostleg
Copy link

Ghostleg commented May 26, 2021

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)
            }
        }
    }
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label May 26, 2021
@sbrannen sbrannen added the in: web Issues in web modules (web, webmvc, webflux, websocket) label May 31, 2021
@sdeleuze sdeleuze self-assigned this May 31, 2021
@emrearslan
Copy link

Is there any progress on this?

@sdeleuze sdeleuze added theme: kotlin An issue related to Kotlin support type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jun 12, 2023
@sdeleuze sdeleuze added this to the 6.0.x milestone Jun 12, 2023
@sdeleuze
Copy link
Contributor

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.

@sdeleuze
Copy link
Contributor

See potentially related issue #27522.

@sdeleuze
Copy link
Contributor

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.

sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Aug 29, 2023
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Aug 29, 2023
@IevgenBizz
Copy link

IevgenBizz commented Nov 10, 2023

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 #27522)

@sdeleuze
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

6 participants