I have such a situation:
I would like my route NOT to be re-triggered while massive task is underway. That is, timer may issue event but it should somehow not lead to trigger route. When massive task is finished, it should be possible for timer to start route again.
What would be the best way to achieve this behaviour?
This is a dsl version that has worked for me:
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))
;
Well, my first reflex would be to use the timer
's period
option without the fixedRate
option (i.e. set the fixedRate
option to false):
So, declaring:
from("timer:myTask?[other_options]&fixedRate=false")
.to("direct:lengthyProcessingRoute")
should wait for the task to complete before triggering the timer again.
For instance, declaring a route like (fixedRate
is false by default):
from("timer:sender?delay=5s&period=3s")
.log("Ping!")
.delay(5000)
.log("Ping2!");
will always give the output of:
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!
However, this will only work if your lengthy processing route is synchronous in nature. If it's not, then you would have to do something similar to what JimNicholson is suggesting in his answer.
I would create a bean to hold the running/finished state of the route with methods to set the state and a method to test the state. Then I would do something like this:
<route>
<from uri="timer:...">
<filter>
<method ref="routeStateBean" method="isStopped">
<to uri="bean:routeStateBean?method=routeStarted"/>
....
<to uri="bean:routeStateBean?method=routeStopped"/>
</filter>
</route>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With