Spring Integration:优雅地停止流程并避免MessageDispatchingException

时间:2018-03-13 20:35:31

标签: java spring spring-integration

我的程序必须能够停止并再次启动它。 我使用IntegrationFlowRegistration.stop()/ .start()方法。 问题是wenn Lifecycle组件被停止了数百个MessageDispatchingException被抛出。 可能是因为某些组件已停止,而另一些组件仍在尝试传递某些消息。 是否有一些最佳做法来阻止流动? 阻止flow.inputChannel的一些标准方法,等到所有通道都没有要传递的消息,然后停止流的所有组件? 以下是junit测试,以重现此行为。

@Test
public void testStopFlowGracefully() {
    final Queue<List<Integer>> inQueue = new LinkedBlockingQueue<>();
    MessageSource<List<Integer>> inMs = new AbstractMessageSource<List<Integer>>() {
        @Override
        public String getComponentType() {
            return null;
        }

        @Override
        protected Object doReceive() {
            return inQueue.poll();
        }
    };

    QueueChannel resultChannel = new QueueChannel();

    IntegrationFlow integrationFlow = IntegrationFlows
            .from(inMs, c->c.poller(Pollers.fixedRate(50)))
            .split()
            .channel(c -> c.executor(Executors.newFixedThreadPool(5)))
            .<Integer, Integer>transform(p -> {
                try {
                    Thread.sleep(100);
                } catch (Exception e) { }                   
                return p * 2;})
            .log(l -> "!!!!!!!!!!!!!!!!!!!!!!! transformed int="+l)
            .channel(resultChannel)
            .get();

    IntegrationFlowRegistration registration = this.flowContext.registration(integrationFlow).register();

    inQueue.add(IntStream.rangeClosed(1, 100).boxed().collect(Collectors.toList()));
    try {
        Thread.sleep(2000);
    } catch (Exception e) {
    }
    registration.stop();

    Message<?> msg = resultChannel.receive(2000);
    assertThat(msg).isNotNull();
}

0 个答案:

没有答案