-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Expected Behavior
Given some code like this:
.scatterGather(
scatterer -> scatterer
.applySequence(true)
.recipientFlow(IntegrationFlows.from(MessageChannels.executor(myExecutorService))
.gateway(mySubFlow1())
.get())
.recipientFlow(IntegrationFlows.from(MessageChannels.executor(myExecutorService))
.log(/* some logging here */)
.gateway(mySubFlow2())
.get()),
gatherer -> gatherer
.releaseStrategy(defaultReleaseStrategy)
.outputProcessor(myOutputProcessor))
if I move the .log() statement down one line, like this:
.scatterGather(
scatterer -> scatterer
.applySequence(true)
.recipientFlow(IntegrationFlows.from(MessageChannels.executor(myExecutorService))
.gateway(mySubFlow1())
.get())
.recipientFlow(IntegrationFlows.from(MessageChannels.executor(myExecutorService))
.gateway(mySubFlow2())
.log(/* some logging here */)
.get()),
gatherer -> gatherer
.releaseStrategy(defaultReleaseStrategy)
.outputProcessor(myOutputProcessor))
I would expect everything to work exactly the same, except that the .log() statement is executed after the .gateway() call.
Current Behavior
Changing the position of .log() changes the behavior of the flow. In this case, the releaseStrategy never receives the output of the second recipientFlow. The reason for this is explained in the JavaDoc, where we read - "When this operator is used in the end of flow, it is treated as one-way handler without any replies to continue.".
Context
This is not the behavior one would expect, it's not intuitive, and it has caused an unexpected bug in our team that took a long time to debug. (https://en.m.wikipedia.org/wiki/Principle_of_least_astonishment) We were quite surprised to learn about .logAndReply() and consider it one of those things that make the SI DSL hard to work with. Sometimes things just don't work and you have not reason why and no easy and no quick way to find the cause.
IMO the .log() statement should behave the same no matter where you place it in a flow. If it is placed at the end of a flow, and if this flow has no output channel, throw the usual exception, and the developer will quickly realize they need to add .nullChannel() or something similar. Perhaps you could even detect if .log() needs to reply or not (it seems you can detect if it is at the end of a flow, so maybe at that moment you can also detect if an output channel is configured for this flow) ?
logAndReply() could be deprecated and ultimately removed.
Am I missing something that would prevent such a solution ?