我有一个集成流程,其中一些步骤是异步的,一些是同步的。我想使用barrier
来阻止Main
线程,直到完成所有异步任务。根据文档,有两种方法可以使用屏障。
在我的用例中,流中会出现一条消息,然后经过几个组件,直到它到达completed
频道。我想要阻止主线程,直到原始消息到达完成的通道。因此,在达到completed
状态后,使用选项#2并调用屏障触发器方法似乎是合适的。这似乎不起作用。这是我的流程的简化版本。
<int:gateway
service-interface="...BarrierGateway"
id="barrierGateway" default-request-channel="input">
</int:gateway>
<int:channel id="input">
<int:dispatcher task-executor="executor" />
</int:channel>
<int:service-activator input-channel="input" output-channel="completed">
<bean class="...BarrierSA" />
</int:service-activator>
<int:channel id="completed" />
<int:service-activator input-channel="completed"
ref="barrier1.handler" method="trigger" />
<int:barrier id="barrier1" input-channel="input" timeout="10000" />
我正在向gateway
发送消息,将消息传递给使用input
的{{1}}频道,以便启动新线程以向前传递消息。此时,我希望在dispatcher
线程完成流程时阻止main
线程。其余的流程很简单。在返回消息以模拟延迟之前,我的Executor-1
会休眠3秒钟。一旦在service-activator
通道中收到消息,服务激活器就应该调用completed
方法,并且仅在此时,应该释放主线程。而是在调度程序启动新线程后立即释放主线程。我已经尝试过指定一个常量的相关id('abc'),但这并没有帮助。
答案 0 :(得分:2)
我发现你陷入了陷阱。
<int:barrier>
仅在消息消息上挂起Thread,但只挂起那个将消息带给他的Thread。查看您的配置,input
频道与Executor
相同。 ExecutorChannel
将消息转移到另一个线程但不挂起调用者线程的目的。
另一方面,input
还有一个错误。您为他声明了两个订阅者,其中只有一个订阅者将被round-robin
平衡策略调用。
要修复您的任务,我们应该再将一个顶级频道设为<publish-subscribe-channel>
。而且,现在你可以拥有两个订阅者。
其中一个应该是<bridge>
input
的{{1}}。另一个是期望的ExecutorChannel
。只有现在它才能暂停(以你的方式阻止)来自<barrier>
的主线程。
从另一方面来看,更简单的解决方案是根本不使用<gateway>
。 <barrier>
能够阻止调用者的线程并等待回复。当然,当网关方法不是<gateway>
时,它才有效。
还有一点指向您的配置:如果您不等待网关中的回复,则void
将失败并显示
<barrier>
所以,考虑在那里使用throw new DestinationResolutionException("no output-channel or replyChannel header available");
作为一个井。