Spring Integration:使用fixedDelay轮询整个流程执行

时间:2018-03-24 21:35:57

标签: spring spring-integration

在我的集成流程中,我使用JdbcPollingChannelAdapter来提供实体键列表,处理这些实体并将下一个sql查询的时间窗口设置为下一次迭代(基于实体的最后修改时间)。 在处理延迟或处理错误的情况下,下一次迭代不应该发生,并且MessageSource应该等到当前流执行成功或超时发生。所以在每个时刻最大应该处理一个密钥列表。

是否有优雅的方法来设置Pollers.fixedDelay(...)不是为了MessageSource而是为了整个流程执行,以便在当前被合并后开始下一个流程执行?

    @Test
    public void testDelayedExecutionSequence() {
    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();
        }
    };

    final int messagesPerStep = 100;
    final int maxIterations = 10;
    for(int iteration = 1, from=1, to=messagesPerStep; iteration <= maxIterations; iteration++, from += messagesPerStep, to += messagesPerStep) {
        System.out.println(String.format("add list from=%d, to=%d", from, to));
        inQueue.add(IntStream.rangeClosed(from, to).boxed().collect(Collectors.toList()));
    }

    final AtomicInteger amqpSendCounter = new AtomicInteger();
    final AtomicInteger iterationCounter = new AtomicInteger();
    final List<Integer> resultSequence = new ArrayList();

    IntegrationFlow integrationFlow = IntegrationFlows
            .from(inMs, c->c.poller(Pollers.fixedDelay(50).maxMessagesPerPoll(1)))
            .split()
            .channel(c -> c.executor(Executors.newFixedThreadPool(10)))
            .<Integer, Integer>transform(p -> {
            if(p == 405) {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                }
            }
            return p;})             
            .handle((p, h) -> {amqpSendCounter.incrementAndGet(); return p;})
            .aggregate()
            .log(l -> "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! after agregate(): "+l)
            .<List<Integer>>handle(m -> {iterationCounter.incrementAndGet();
                Integer firstIntInList = ((List<Integer>)m.getPayload()).get(0);
                resultSequence.add(firstIntInList / 100);
            })
            .get();

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

    try {
        Thread.currentThread().sleep(3000);
    } catch (InterruptedException e) {
    }

    assertThat(iterationCounter.get()).as("iterationCounter.get").isEqualTo(maxIterations);
    assertThat(resultSequence).as("result sequence").isEqualTo(IntStream.rangeClosed(0, 9).boxed().collect(Collectors.toList()));
}

1 个答案:

答案 0 :(得分:1)

您需要查看Conditional polling并且在某些状态发生变化之前不要再调用receive()PollSkipAdvice应该是你的不错选择。