MH: Async by default for reactive output channel (#8612)

When we configure an output channel for the handler as a `FluxMessageChannel`,
in most cases we assume an async processing for the reply.
Especially this is critical when reply is a reactive type, so in the async
mode it is "flattened" by the mentioned `FluxMessageChannel`.
Therefore, it is a bit awkward to require to set async explicitly,
when we have already configured output channel as a `FluxMessageChannel`

* Remove redundant config for async from `R2dbcDslTests`
* Mention the change in the docs
This commit is contained in:
Artem Bilan
2023-05-08 10:30:41 -04:00
committed by GitHub
parent 9e7b20a059
commit b999ac109c
6 changed files with 21 additions and 4 deletions

View File

@@ -71,7 +71,7 @@ IntegrationFlow r2dbcDslFlow(R2dbcEntityTemplate r2dbcEntityTemplate) {
.bindFunction((DatabaseClient.GenericExecuteSpec bindSpec, Person o) ->
bindSpec.bind("id", o.getId())),
e -> e.poller(p -> p.fixedDelay(100)))
.<Mono<?>>handle((p, h) -> p, e -> e.async(true))
.handle((p, h) -> p)
.channel(MessageChannels.flux())
.get();
}

View File

@@ -42,7 +42,7 @@ See the next section for more information.
=== Reactive Reply Payload
When a reply producing `MessageHandler` returns a reactive type payload for a reply message, it is processed in an asynchronous manner with a regular `MessageChannel` implementation provided for the `outputChannel` and flattened with on demand subscription when the output channel is a `ReactiveStreamsSubscribableChannel` implementation, e.g. `FluxMessageChannel`.
When a reply producing `MessageHandler` returns a reactive type payload for a reply message, it is processed in an asynchronous manner with a regular `MessageChannel` implementation provided for the `outputChannel` (the `async` must be set to `true`) and flattened with on demand subscription when the output channel is a `ReactiveStreamsSubscribableChannel` implementation, e.g. `FluxMessageChannel`.
With a standard imperative `MessageChannel` use-case, and if a reply payload is a *multi-value* publisher (see `ReactiveAdapter.isMultiValue()` for more information), it is wrapped into a `Mono.just()`.
A result of this, the `Mono` has to be subscribed explicitly downstream or flattened by the `FluxMessageChannel` downstream.
With a `ReactiveStreamsSubscribableChannel` for the `outputChannel`, there is no need to be concerned about return type and subscription; everything is processed smoothly by the framework internally.

View File

@@ -225,6 +225,10 @@ If the service completes the future with an `Exception`, normal error processing
An `ErrorMessage` is sent to the `errorChannel` message header, if present.
Otherwise, an `ErrorMessage` is sent to the default `errorChannel` (if available).
Starting with version 6.1, if the output channel of the `AbstractMessageProducingHandler` is configured to a `ReactiveStreamsSubscribableChannel`, the async mode is turned on by default.
If the handler result is not a reactive type or `CompletableFuture<?>`, then regular reply producing process happens despite the output channel type.
See also <<./reactive-streams.adoc#reactive-streams,Reactive Streams Support>> for more information.
[[service-activator-return-type]]
==== Service Activator and Method Return Type

View File

@@ -51,6 +51,9 @@ Since `IntegrationComponentSpec` is a `FactoryBean`, its bean definition must st
The Java DSL and the framework by itself will manage the `IntegrationComponentSpec` lifecycle.
See <<./dsl.adoc#java-dsl, Java DSL>> for more information.
- The `AbstractMessageProducingHandler` is marked as an `async` by default if its output channel is configured to a `ReactiveStreamsSubscribableChannel`.
See <<./service-activator.adoc#async-service-activator,Asynchronous Service Activator>> for more information.
[[x6.1-web-sockets]]
=== Web Sockets Changes