JobsPlugin 呼び出しを見ると、各ジョブ実行の最後にジョブの次の計画実行日が再計算されるため、ソリューションが機能するかどうかはわかりません。
これが私の解決策です。ジョブのcron属性に基づいてジョブの実行日を計算できるように、JobSchedulerクラスを再作成します。可視性ルールのために、いくつかのジョブ属性を再宣言する必要がありました。
だから私の仕事のクラスは
package jobs;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import play.jobs.Job;
public class MyJob extends Job<Object> {
public Date nextPlannedExecution = null;
public String cron = null;
@Override
public void _finally() {
// cron is null if we force job execution
if (cron != null) {
// As the job don't have a Cron annotation, super call does nothing
super._finally();
JobScheduler.scheduleForCRON(this, cron);
}
}
void setExecutor(ExecutorService executor) {
this.executor = executor;
}
}
私のスケジューラ クラスはパッケージ ジョブです。
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import models.Partner;
import play.Logger;
import play.jobs.Job;
import play.jobs.JobsPlugin;
import play.libs.Expression;
import play.libs.Time.CronExpression;
public class JobScheduler {
public static synchronized void scheduleCsvExportJob(String cron) {
MyJob myJob = null;
for (Job<?> job : JobsPlugin.scheduledJobs) {
if (job instanceof MyJob) {
myJob = (MyJob) job;
}
}
if (myJob == null) {
myJob = new MyJob();
JobsPlugin.scheduledJobs.add(myJob);
}
myJob.cron = cron;
scheduleForCRON(myJob, myJob.cron);
}
public static void scheduleForCRON(MyJob job, String cron) {
try {
Date now = new Date();
cron = Expression.evaluate(cron, cron).toString();
CronExpression cronExp = new CronExpression(cron);
Date nextDate = cronExp.getNextValidTimeAfter(now);
if (nextDate != null && !nextDate.equals(job.nextPlannedExecution)) {
job.nextPlannedExecution = nextDate;
JobsPlugin.executor.schedule((Callable<?>) job, nextDate.getTime() - now.getTime(),
TimeUnit.MILLISECONDS);
job.setExecutor(JobsPlugin.executor);
}
} catch (Exception ex) {
Logger.error(ex, "Cannot schedule job %s", job);
}
}
}
このコードを使用すると、JobScheduler.scheduleMyJob を呼び出して、適切なスケジューリング式を渡すことでジョブのスケジューリングを変更できます: 0 0 2 * * ? 2時間ごと。
ジョブが終了すると、_finally メソッドは、新しいスケジューリング時間を設定する scheduleForCRON メソッドを呼び出します。
たとえば、GUI ボタンを使用してジョブを強制的に実行する場合は、cron 属性を定義せずにインスタンスを作成できます。このインスタンスは最後に再スケジュールされません。