Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reschedule a task with spring scheduler

I have a spring scheduler which has three tasks with different triggers(cron triggers). For each of those tasks, I have a UI which can modify the cron expression. I want to reschedule the tasks when the service receives the request to update. Below is my Scheduler configuratin. How can I change the schedule of one of the tasks at runtime(When UI sends the request to update the cron expression in the DB). With the below approach, the scheduler is only updated with the next schedule. i.e. the nextExecutionTime() method is called when the trigger is called.

@Configuration
@EnableScheduling
public class Config implements SchedulingConfigurer {

    @Inject
    MyDao db;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);

        List<TaskConfig> conf = db.readTaks();
        conf.forEach((TaskConfig aTask) -> {
            taskRegistrar.addTriggerTask(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Running task + " + aTask.getName());
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(final TriggerContext triggerContext) {
                    String expression = aTask.getCronExpression();
                    CronTrigger trigger = new CronTrigger(expression);
                    Date nextExec = trigger.nextExecutionTime(triggerContext);
                    return nextExec;
                }
            });
        });
    }
}

Edit: Eg. Consider my cron expression is set to trigger initially at 40th minute of every hour and the current time is 11:20 AM. Now, if I update the cron now to trigger at 25th minute, I expect the task to be trigger at 11:25 AM. But with the above code it triggers at 11:40AM and then triggers at 12:25PM. This is not the behavior I want.

like image 363
pravat Avatar asked Nov 07 '22 19:11

pravat


1 Answers

I think you have 2 options:

  1. Refresh the context; this will work assuming you updated the database so that db.readTaks() returns the updated schedule.
  2. Add a trigger with the new time, to be executed once. This can be done by injecting the ScheduledTaskRegistrar, and adding a trigger for 11:25am like in your example. Here's a crude example:

    @Autowired
    private ScheduledTaskRegistrar taskRegistrar;
    
    void runOnce() {
        taskRegistrar.scheduleCronTask(task);
    }
    
like image 137
Abhijit Sarkar Avatar answered Nov 15 '22 05:11

Abhijit Sarkar