If the controller method return type is not asynchronous, it should be running in Elastic thread pool.
In WebFlux, we should support asynchronous and synchronous both. if the controller method's return type is Mono/Flux/Future/CompleteableFuture, we should runnint this controller in synchronous(IO) thread, but if they just not want running in Asychronous Mode, they may invoke database or something else (IO operation), they just not return Mono/Flux type, and we throw them into elastic thread pool.
It's very helpful to many projects, to gain asynchronous and synchronous advances.
Comment From: pivotal-issuemaster
@fugui Please sign the Contributor License Agreement!
Click here to manually synchronize the status of this Pull Request.
See the FAQ for frequently asked questions.
Comment From: pivotal-issuemaster
@fugui Thank you for signing the Contributor License Agreement!
Comment From: rstoyanchev
WebFlux does support both blocking and non-blocking but by default it assumes non-blocking handling. This is irrespective of the return type actually, and a controller method that returns an actual value is not necessarily blocking. We don't want to force a switch of threads when we don't know if the controller is actually performing a blocking operation or not. There would have to be something more explicit to indicate that.
You can see a longer discussion and decision under #21184. For now the conclusion is that controller methods need to explicitly use .publishOn
to switch threads where needed.
Comment From: fugui
For the now the conclusion is that controller methods need to explicitly use .publishOn to switch threads where needed.
Yes, I got it. but when you are in a big business development team, it not easy to enable everyone to understand asynchronous , and be professional in reactor.
And I also think @Async annotation is not a good solution, it's too boring to write everywhere.
Might I add a global configuration to enable global controller returntype detection?
if ( isAutoBlockingDetection && isAsyncReturnType(method.getReturnType()) ) {
argumentValues.publishOn(Schedulers.boundedElastic());
}
Comment From: rstoyanchev
@Async
does not fit because it expects void
or Future
as the return type. It's also confusing to use because in WebFlux the default assumption is "async" so it would rather have to be something that labels a method (or class) as "blocking".
As a compromise we could expose a property on RequestMappingHandlerAdapter
with a Predicate<HandlerMethod>
to help decide if a method is blocking or not, in which case we would switch threads or not. We'd call this only if the return type is not asynchronous. You could then simply return true
or use some other strategy to determine based on the controller method.
Comment From: fugui
Thanks, I think this " on RequestMappingHandlerAdapter with a Predicate
Comment From: rstoyanchev
On further thought, and team discussion, we'll defer this to 6.0, to consider more comprehensively, and expose as a first-class feature. It is something that affects more broadly all places where we invoke annotated methods on a reactive foundation, which is in WebFlux but also in RSocket. We may consider adding an annotation as well as a global option that enables some strategy to determine methods that may block.
In the mean time, to enable globally, you could extend RequestMappingHandlerAdapter
and override its handle
method.
Comment From: rstoyanchev
This is now superseded by #30678.