2016-12-16 6 views
1

私は春に予定された仕事をしています。私は自分のデータベースからそのcronを取得します。 実行するたびに、次の実行時間が更新されます。したがって、10分ごとに実行するように設定されている場合は、その値をデータベースに変更して15分ごとにそのジョブをスケジュールすることができます。春更新スケジューラ

問題は、更新されたcronが実行されるのを待たなければならないということです。ジョブが15分ごとにスケジュールされ、2分ごとにこの値を変更したい場合、次の実行を待たなければなりません(最大15分)、2分ごとにこのジョブを実行します。

データベースを更新した後にこのジョブを再スケジュールする方法はありますか?

私はこのBeanを破棄してリフレッシュすると思っていましたが、動作していません(おそらく実装できませんでした。おそらく、メソッドconfigureTaskを実行するイベントをトリガする方法があります。

私のスケジュールされたジョブのスニペットです。

@EnableScheduling 
@Component 
public class MyClass implements SchedulingConfigurer { 

    private static final String JOB = "My personal task"; 

    @Autowired 
    JobRepository jobRepository; 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 
     scheduledTaskRegistrar.addTriggerTask(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("Hello World!"); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB); // read from database 
       String cron = byJobNameIgnoreCase.getCrontab(); 
       CronTrigger trigger = new CronTrigger(cron); 
       return trigger.nextExecutionTime(triggerContext); 
      } 
     }); 
    } 

} 
+0

私は、このリンクを見つけたが、それは動作していない.. [http://stackoverflow.com/questions/39152599/interrupt-spring-scheduler-task-before-next-invocation?rq=1] –

答えて

0

これを管理するには、自分のジョブを管理するSchedulerOrchestratorを作成しました。ジョブにはSchedulerFutureが含まれています。

ここで私が望むコードは他の人を助けることができます。

のが私の仕事で実装されるインタフェースを見てみましょう:

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

すべてのジョブが停止するScheduledFutureを必要としTaskSchedulerがスケジュールされるautowireする必要があります。ここで一つの仕事のサンプル(あなたが好きなだけ作成することができます):

@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(); 
    } 

} 

最後に、我々は、オーケストレータに私たちの仕事を追加することができます。

@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

は、この方法を検討してください。スケジュールされたタスクを追加および削除する代わりに、実際の瞬間を毎分(または別の精度で)確認し、必要な作業を直ちに実行できます。これは簡単になります。 Quartz Schedulerをチェックすると、そのCronExpressionはisSatisfiedBy(Date date)メソッドを持ちます。

@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 
} 
関連する問題