Spring update scheduler

后端 未结 2 476
遥遥无期
遥遥无期 2020-12-29 17:36

I have a scheduled job in Spring, I get its cron from my database. Every time it is executed, the next execution time is updated. So, if it is configured to run every 10 min

相关标签:
2条回答
  • 2020-12-29 18:25

    Consider this approach. Instead of adding and deletion scheduled tasks, you may check every minute (or with another precision) actual moment against your views and run necessary tasks immediately. This will be easier. Check Quartz Scheduler, its CronExpression has isSatisfiedBy(Date date) method.

    @Scheduled(cron = "5 * * * * *) // do not set seconds to zero, cause it may fit xx:yy:59
    public void runTasks() {
         LocalTime now = LocalTime.now(); // or Date now = new Date();
        // check and run
    }
    
    0 讨论(0)
  • 2020-12-29 18:34

    To manage this, I created a SchedulerOrchestrator, which manages my jobs. The jobs contain a SchedulerFuture.

    Here the code that I hope can help someone else.

    Let's start with an interface which will be implemented by my jobs:

    public interface SchedulerObjectInterface {    
        void start();
        void stop();
    }
    

    Every job needs a ScheduledFuture to stop and needs to autowire a TaskScheduler to be scheduled. Here a sample of one job (you can create as many as you want):

    @Component
    public class MyFirstJob implements SchedulerObjectInterface {
    
        private static final Logger log = LoggerFactory.getLogger(MyFirstJob.class);
    
        public static final String JOB = "MyFirstJob";
    
        @Autowired
        JobRepository jobRepository;
    
        private ScheduledFuture future;
    
        @Autowired
        private TaskScheduler scheduler;
    
    
        @Override
        public void start() {
            future = scheduler.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(JOB + "  Hello World! " + new Date());
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    String cron = cronConfig();
                    System.out.println(cron);
                    CronTrigger trigger = new CronTrigger(cron);
                    return trigger.nextExecutionTime(triggerContext);
                }
            });
    
        }
    
        @Override
        public void stop() {
            future.cancel(false);
        }
    
        // retrieve cron from database
        private String cronConfig() {
            JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB);
            return byJobNameIgnoreCase.getCrontab();
        }
    
    }
    

    Finally we can add our jobs to an orchestrator:

    @Configuration
    public class SchedulerOrchestrator {
    
        private static final Logger log = LoggerFactory.getLogger(SchedulerOrchestrator.class);
    
        private static Map<String, SchedulerObjectInterface> schduledJobsMap = new HashMap<>();
    
        @Autowired
        JobRepository jobRepository;
    
        @Autowired
        MyFirstJob myFirstJob;
    
        @Autowired
        MySecondJob mySecondJob;
    
        @Autowired
        TaskScheduler scheduler;
    
        @PostConstruct
        public void initScheduler() {
            schduledJobsMap.put(MyFirstJob.JOB, myFirstJob);
            schduledJobsMap.put(MySecondJob.JOB, mySecondJob);
    
            startAll();
        }
    
        public void restart(String job) {
            stop(job);
            start(job);
        }
    
        public void stop(String job) {
            schduledJobsMap.get(job).stop();
        }
    
        public void start(String job) {
            schduledJobsMap.get(job).start();
        }
    
        public void startAll() {
            for (SchedulerObjectInterface schedulerObjectInterface : schduledJobsMap.values()) {
                schedulerObjectInterface.start();
            }
        }
    
        @Bean
        public TaskScheduler scheduler() {
            return new ThreadPoolTaskScheduler();
        }
    }
    
    0 讨论(0)
提交回复
热议问题