spring-integration icon indicating copy to clipboard operation
spring-integration copied to clipboard

Scatter Gather Blocking threads when used along with WebFlux & Netty

Open sirimamilla opened this issue 5 years ago • 5 comments

Affects Version(s): 5.3


Scatter Gather is blocking on thread waiting for response at gatherResultChannel.receive() as this is blocking call.

Is there any alternative option to avoid waiting for response like this, instead subscribe to the response from some subscribable channel or any other alternative(not able to think of a solution) so this will work perfectly fine without holding up on threads.

I have been looking out for solutions but couldn't find any perfect one.

sirimamilla avatar Feb 20 '20 16:02 sirimamilla

Consider to make an inputChannel for Scatter-Gather as an ExecutorChannel. This way you'll shift a WebFlux work to a separate thread and it won't see that blocking any more. Kinda non-reactive solution, but we definitely can't make a Scatter-Gather as non-blocking. There is still an aggregator involved with its locking on groups for completion.

artembilan avatar Feb 20 '20 17:02 artembilan

Hi @artembilan,

Similar to the way, we have WebFlux as an alternative to Http, can we consider a new Scatter Gather that can be reactive or something like that. Just a thought.

Aggregator Groups doesnt hold threads. so they will work perfectly with Reactive framework.

sirimamilla avatar Feb 29 '20 00:02 sirimamilla

Yeah... That has crossed my mind as well. We have already a https://github.com/spring-projects/spring-integration/blob/master/spring-integration-core/src/main/java/org/springframework/integration/aggregator/FluxAggregatorMessageHandler.java, so it definitely possible to take a look into reactive scatter-gather implementation...

artembilan avatar Feb 29 '20 01:02 artembilan

Hi @artembilan,

My further tests bumped me into Gateway also behaving the same way, where it blocks the reactor threads and is causing the effect of reactive framework to not be fully utilized.

Message<?> gatherResult = gatherResultChannel.receive(this.gatherTimeout); is the one blocking the thread.

The problem with all of these patterns is common, we are making the parent thread wait, for executor channels to complete the request execution rather than handing the monitoring for response to some monitor thread(Just a thought).

sirimamilla avatar Feb 29 '20 01:02 sirimamilla

To make a gateway reactive or non-blocking, you need to consider to have a specific return type on the gateway method. See docs for more info: https://docs.spring.io/spring-integration/docs/5.2.3.RELEASE/reference/html/messaging-endpoints.html#async-gateway

we are making the parent thread wait

That's really the point of those components. We don't advertise that Spring Integration is fully reactive & non-blocking. We just need to deal with some workarounds for reactive programming how to call blocking code or develop reactive alternatives. And this is indeed what we are pursuing with issues similar to this.

artembilan avatar Mar 02 '20 19:03 artembilan