使用barrier等待集成流程完成

时间:2016-04-20 16:25:27

标签: spring spring-integration

我有一个集成流程,其中一些步骤是异步的,一些是同步的。我想使用barrier来阻止Main线程,直到完成所有异步任务。根据文档,有两种方法可以使用屏障。

  1. 将第二个触发消息发送到屏障的输入通道。
  2. 手动调用屏障的触发方法
  3. 在我的用例中,流中会出现一条消息,然后经过几个组件,直到它到达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'),但这并没有帮助。

1 个答案:

答案 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"); 作为一个井。