Unterbrechen Sie die Federplaneraufgabe vor dem nächsten Aufruf

Ich habe eine Spring-Boot-Anwendung, die ein Orchestrierungsdienst für mehrere andere processe sein wird, die wir auslösen möchten. Ich habe es derzeit eingerichtet mit Spring Scheduling ziehen Cron dynamisch aus einer database. Ich warf eine Rest-Methode ein, um den process auszulösen, um neue Cron-Informationen aus der database zu ziehen. Diese Logik funktioniert alle korrekt. Das einzige “Problem” ist, dass es die neuen Cron-Informationen erst beim nächsten geplanten Lauf verwendet, der zur eigentlichen Frage kommt. Gibt es eine Möglichkeit, den aktuellen Trigger zu unterbrechen und ihn erneut mit den aktualisierten Cron-Informationen zu planen. Hier ist die Anwendung als Referenz:

package com.bts.poc; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.Date; @SpringBootApplication @EnableScheduling @RestController @RequestMapping("/APSCommon/Scheduling") public class Application implements SchedulingConfigurer { @Autowired private DynamicCron dynamicCron; @Autowired PropertyManager propertyManager; public static void main(String[] args) throws Exception { SpringApplication.run(Application.class); } private String cronConfig() { String cronTabExpression = propertyManager.getProperty("COMPANY", "JOB_NAME","CRON_EXPRESSION"); return cronTabExpression; } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(new Runnable() { @Override public void run() { dynamicCron.runJob(); } }, new Trigger() { @Override public Date nextExecutionTime(TriggerContext triggerContext) { String cron = cronConfig(); CronTrigger trigger = new CronTrigger(cron); Date nextExec = trigger.nextExecutionTime(triggerContext); DynamicCron.cronExpression = cron; return nextExec; } }); } @RequestMapping(value = "/reloadScheduling", method = RequestMethod.GET) public String reloadScheduling() { PropertyManager.setResetProperties(true); return "schedules will be altered next run"; } } 

Wenn Sie also SchedulingConfigurer-> configureTasks verwenden, können Sie in der von mir verwendeten Spring-Version (4.2.7.RELEASE) keinen Zugriff auf die ScheduledFuture (n) erhalten. Von mehreren Posts, die ich gelesen habe, wurde es als mögliche functionalität für die Zukunft erwähnt. Ich habe das umgangen, indem ich Folgendes getan habe:

 package com.bts.poc; import com.bts.poc.service.DynamicCron; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.CronTrigger; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; import java.util.TimeZone; import java.util.concurrent.ScheduledFuture; @SpringBootApplication(exclude = MessageSourceAutoConfiguration.class) @EnableScheduling @RestController public class Application extends SpringBootServletInitializer { @Autowired private DynamicCron dynamicCron; @Autowired private PropertyManager propertyManager; private static List scheduledFutures = new ArrayList<>(); private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); private static TaskScheduler scheduler; @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } private String cronConfig() { return propertyManager.getProperty("COMPANY", "JOB_NAME", "CRON_EXPRESSION"); } @RequestMapping(value = {"scheduling/start"}, method = RequestMethod.GET) public @ResponseBody String startScheduling() { scheduleAll(); LOGGER.info("Scheduling of jobs has been started."); return "Scheduling of jobs has been started."; } @RequestMapping(value = {"scheduling/cancel"}, method = RequestMethod.GET) public @ResponseBody String cancelScheduling() { cancelAll(); LOGGER.info("Cancelling all scheduled jobs."); return "Cancelling all scheduled jobs."; } private void scheduleAll() { LOGGER.info("Scheduling all applications to run."); cancelAll(); //eventually go through the database and load all jobs to be scheduled here. schedule(cronConfig()); } /** * Cancel all the scheduled reports */ private void cancelAll() { for (ScheduledFuture scheduledFuture : scheduledFutures) { scheduledFuture.cancel(true); } scheduledFutures.clear(); } /** * Schedule the scheduled report with the given cron schedule information */ private void schedule(String cronSchedule) { TimeZone tz = TimeZone.getDefault(); LOGGER.info("Setting up application {} to execute with cron string: '{}'.", cronSchedule); CronTrigger trigger = new CronTrigger(cronSchedule, tz); scheduler = scheduler(); if (scheduler == null) { LOGGER.error("Unable to schedule job as scheduler was not found"); return; } ScheduledFuture< ?> future = scheduler.schedule(new DynamicCron(), trigger); scheduledFutures.add(future); } @Bean public TaskScheduler scheduler() { if (scheduler == null) { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); scheduler.afterPropertiesSet(); } return scheduler; } } 

Das repliziert im Grunde die functionalität, die das ScheduledTaskRegistrar bereitstellt, die es Ihnen ermöglicht, die ScheduledFuture (s) zu verwalten. Hoffentlich kann dies jemand anderem in der Zukunft helfen.