Spring Scheduler — Dynamically changing the schedule

@Component
public class SyncScheduler {
@Autowired
private SyncDao syncDao;

public String getFixedDelay() {
return syncDao.getSchedule();
}
@Scheduled(fixedDelayString =
"#{@syncScheduler.getFixedDelay()}")
public void run() {
// sync logic here.
}
}
  • I am scheduling task when the application comes up using a SchedulingConfigurer
  • I am using a Trigger — which is how after every run, the scheduler know when to kick start the next run. It gives a TriggerContext to know when the last run executed/completed. I am particular interested in lastActualExecutionTime() — when the last run started executing so that I can implement a fixed delay.

i.e. I have configured sync with 10 mins.

Say T1 executed at 10:00 and took 5 mins, using this trigger I would say next trigger should be at 10:00 + 10 = 10:10

Say T1 executed at 10:00 and took 12 mins, next trigger should have been at 10:10 but that time has passed already! So it will trigger right away.

This was perfect for my usecase.

  • Then I get a handle to the ScheduledFuture so I can cancel whenever I need to change the schedule; or know when the next schedule will kick start
ScheduledFuture<?> schedule(Runnable task, Trigger trigger);
public synchronized void updateSchedule( 
Integer syncScheduleInSeconds)
{
LOGGER.info(“Sync schedule is updated in DB”);
this.scheduleInSeconds = syncScheduleInSeconds;
long delayInSeconds= this.scheduledFuture
.getDelay(TimeUnit.SECONDS);
if (delayInSeconds < 0) {
LOGGER.info(“Sync run is already in process. New schedule
will take effect after the current run”);
} else if (delayInSeconds <
CANCEL_SCHEDULED_TASK_DELAY_THRESHOLD_IN_SECONDS){
LOGGER.info(“Next sync is less than {} seconds away. after
the next run, schedule will automatically be
adjusted.”,
CANCEL_SCHEDULED_TASK_DELAY_THRESHOLD_IN_SECONDS);
} else {
LOGGER.info(“Next sync is more than {} seconds away.
scheduledFuture.delay() is {}. Hence cancelling the
schedule and rescheduling.”,
CANCEL_SCHEDULED_TASK_DELAY_THRESHOLD_IN_SECONDS,
delayInSeconds);
this.scheduledFuture.cancel(false);
LOGGER.info(“Reconfiguring sync for {} with new schedule
{}”, jobName, syncScheduleInSeconds);
configureTasks(this.scheduledTaskRegistrar);
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Vinodhini Chockalingam

Vinodhini Chockalingam

Not a blogger. I mostly move my well-written notes here.