我有这样的情况:
我希望我的路线不会在大规模任务正在进行时重新触发。也就是说,计时器可能会发出事件,但它应该以某种方式不会导致触发路由。 当大量任务完成后,计时器应该可以再次开始路由。
实现这种行为的最佳方式是什么?
答案 0 :(得分:1)
我会创建一个bean来保存路由的运行/完成状态,其中包含设置状态的方法和测试状态的方法。然后我会做这样的事情:
<route>
<from uri="timer:...">
<filter>
<method ref="routeStateBean" method="isStopped">
<to uri="bean:routeStateBean?method=routeStarted"/>
....
<to uri="bean:routeStateBean?method=routeStopped"/>
</filter>
</route>
答案 1 :(得分:1)
这是一个对我有用的dsl版本:
private static final AtomicBoolean readyToProcess = new AtomicBoolean(true);
public static boolean readyToProcess() {
boolean readyToProcess = AlarmRouteBuilder.readyToProcess.get();
if (readyToProcess) {
AlarmRouteBuilder.readyToProcess.set(false);
}
return readyToProcess;
}
@Override
public void configure() throws Exception {
from("timer://alarm-poll?period=5s").routeId("alarm-poll")
.log(LoggingLevel.INFO, "Start Timer")
.filter(method(AlarmRouteBuilder.class, "readyToProcess"))
.to("direct:alarm-dostuff")
.end()
.log(LoggingLevel.INFO, "End Timer")
;
from("direct:alarm-dostuff").routeId("alarm-dostuff")
// .process(exchange -> readyToProcess.set(false))
.process(exchange -> doStuff())
.process(exchange -> readyToProcess.set(true))
;
答案 2 :(得分:0)
好吧,我的第一反应就是使用timer
period
选项而不使用fixedRate
选项(即将fixedRate
选项设置为false) :
所以,声明:
from("timer:myTask?[other_options]&fixedRate=false")
.to("direct:lengthyProcessingRoute")
应该在再次触发计时器之前等待任务完成。
例如,声明类似(fixedRate
的路由默认为false):
from("timer:sender?delay=5s&period=3s")
.log("Ping!")
.delay(5000)
.log("Ping2!");
总是会输出:
2016-08-26 12:36:48.130 INFO 5775 --- [ timer://sender] route1 : Ping!
2016-08-26 12:36:53.133 INFO 5775 --- [ timer://sender] route1 : Ping2!
2016-08-26 12:36:53.135 INFO 5775 --- [ timer://sender] route1 : Ping!
2016-08-26 12:36:58.138 INFO 5775 --- [ timer://sender] route1 : Ping2!
但是,只有当您的冗长处理路线本质上是同步的时,这才有效。如果不是,那么你将不得不做类似于JimNicholson建议in his answer的事情。