Timer Job Service
The TimerJobService allows you to schedule events on a specific timestamp. It is implemented using the TimerJob
dataElement which must be enabled through the #processAutomation.timerJob tag or the following option:
The easiest way to use the service is through the TimerField Trigger which schedules a transition when the timestamp in a field is reached.
The service can be consumed directly as well, which the remainder of this article will be about.
Using the service
To start using the service it needs to be injected as an EJB.
@EJB
TimerJobService timerJobService;
void scheduleTask(Context context) {
TimerJob job = TimerJob
.data("my-timer-type", "data")
.keyed("my-job")
.on(Instant.now().plusSeconds(120));
this.timerJobService.schedule(job, context);
}
This snippet already shows most of the API. A TimerJob has the following properties:
type(String) An identifier on which can be decided how to handle the TimerJob.data(Object) The data object. Must be jackson serializable.key(String) The key of the timer. If two timers with the same key are scheduled, the first one is cancelled. If no key is provided, a UUID will be used as the key.timestamp(Instant/Date) The moment the timer should go off. If no timestamp is provided, it will be scheduled immediately.
Once the timer goes off, a TimerJobEvent is fired which can be handled in any way you like.
void onTimer(@Observes TimerJobEvent event) {
if (event.type().equals("my-timer-type")) {
System.out.println(event.payload()); // > "data"
}
}
Dispatching events with callback
To make using the service even easier and type-safe, you can also define your own event classes. Note that these must also be (de)serializable by jackson!
@EJB
TimerJobService timerJobService;
record MyEvent(String name) {}
void scheduleEvent(Context context) {
TimerJob job = TimerJob
.event(new MyEvent("event"))
.on(Instant.now().plusSeconds(30));
this.timerJobService.schedule(job, context);
}
void onEvent(@Observes MyEvent event) {
System.out.println(event.name()); // > event
}
This makes it really easy to implement functionality which must happen at a very specific moment in time.
Under the hood the event will be encoded using it's qualified type as the type, and the event object itself as the
data. A standard TimerJobEventRouter is provided to try and deserialize the TimerJobEvent using the given type.
If that succeeds the event will be fired.