我有一个集成流程,其中一些步骤是异步的,一些步骤是同步的。我想使用 barrier
来阻止 Main
线程,直到所有异步任务完成。根据文档,有两种使用屏障的方法。
- 向屏障的输入 channel 发送第二条触发消息。
- 手动调用栅栏的触发方法
在我的用例中,一条消息进入流中,然后经过多个组件,直到到达 completed
channel 。我希望主线程被阻塞,直到原始消息到达已完成的 channel 。因此,使用选项 #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" />
我正在向网关
发送一条消息,该消息将其传递到使用调度程序
的输入
channel ,以便启动一个新线程转发消息。此时,我想在 Executor-1
线程执行流程时阻止 main
线程。其余流程很简单。我的 service-activator
在返回消息以模拟延迟之前会休眠 3 秒。一旦在完成 channel 中接收到消息,服务激活器就应该调用屏障触发方法,并且只有在此时,主线程才应该被释放。相反,主线程在调度程序启动新线程后立即释放。我尝试指定一个常量相关 ID ('abc'),但这没有帮助。
最佳答案
我发现你陷入了陷阱。
<int:barrier>
仅在消息消息上挂起线程,但仅挂起将该消息带给他的线程。查看您的配置,它是相同的 input
channel Executor
。 ExecutorChannel
的目的将消息转移到不同的线程,但不挂起调用者的线程。
从另一方面来看,你还有一个错误input
。您为他声明了两个订阅者,其中只有一个会被 round-robin
调用。平衡策略。
为了解决您的任务,我们应该再多一个顶级 channel <publish-subscribe-channel>
。是的,现在您已经可以拥有两个订阅者了。
其中一个应该是<bridge>
给您input
ExecutorChannel
。另一个所需的<barrier>
。直到现在它才可以从 <gateway>
挂起(用你的话来说是阻塞)主线程。 .
从另一边来看,更简单的解决方案是不要使用 <barrier>
根本不。 <gateway>
能够阻塞调用者的线程并等待回复。当然,当网关方法不是 void
时,这才有效。 .
还有一点与您的配置有关:如果您不等待网关中的回复,则<barrier>
将失败并显示
throw new DestinationResolutionException("no output-channel or replyChannel header available");
所以,考虑使用一些东西作为 output-channel
有一口井。
关于spring - 使用屏障等待集成流程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36749807/