在我的集成流程中,我使用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()));
}