I am using Hazelcast Scheduled Executor Service in order to run a specific task, on one service instance only. In order to achieve this behavior we take advantage of com.hazelcast.scheduledexecutor.TaskUtils.named(java.lang.String, java.lang.Runnable) decorator to avoid duplicate tasks.
Hazelcast dependencies used:
implementation "com.hazelcast:hazelcast-all:4.2"
implementation "com.hazelcast:hazelcast-kubernetes:2.2.2" // DNS Lookup
We use a hazelcast cluster with one member per service instance
Code example:
public void scheduleTask() {
IScheduledExecutorService es = hazelcastInstance.getScheduledExecutorService("myScheduledExecutor");
try {
es.scheduleAtFixedRate(named("taskName", task)), 0, 30, SECONDS);
} catch (DuplicateTaskException ex) {
System.out.println("Task was already scheduled!");
}
}
The above example manages to partially achieve the desired behavior. The only issue is that every time a new instance spins up, the scheduled executor will run the task on that specific instance. This is not ideal since we would like the task to execute, for example, once every 6 hours.
Is there any way to configure the scheduled executor so that it maintains running the task on the original instance it started and transfers to another instance only if the original one goes down?
The workaround I used was to dispose already scheduled task and schedule again with an initial delay which I calculate based on the last time the task was scheduled.
Something like:
public void scheduleTask() {
IScheduledExecutorService es = hazelcastInstance.getScheduledExecutorService("myScheduledExecutor");
try {
disposePreviousScheduledTasks(es);
es.scheduleAtFixedRate(named("taskName", task)), initialDelay, 30, SECONDS);
} catch (DuplicateTaskException ex) {
System.out.println("Task was already scheduled!");
}
}