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 to help decide" is the best suggestion, it give architects great flexibility to create business frameworks.

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.