玩!框架:我可以重新安排工作吗?

时间:2012-09-21 21:08:01

标签: playframework scheduler jobs playframework-1.x


我正在玩Play!版本1.2.4的框架
在我的应用程序中,我实现了许多预定作业(play.jobs.Job的后代)。

问题

我可以在运行时更改这些作业的计划吗?

我自己的发现

乍一看,Play中的作业安排!通过play.jobs.JobsPlugin完成,java.util.concurrent.ScheduledThreadPoolExecutor反过来使用公开公开的JDK的for (final Object o: JobsPlugin.executor.getQueue()) { ScheduledFuture task = (ScheduledFuture) o; Job job = (Job) Java.extractUnderlyingCallable((FutureTask)task); if (MyJob.class == job.getClass()) { task.cancel(true); new MyJob().every("2h"); break; } } 实例。到目前为止,我提出了以下方法:当时正是改变计划的时刻,我只是迭代执行者的预定工作,取消我需要重新安排的工作并安排相同的工作(更确切地说,同一类的工作)新设置。像这样:

{{1}}

有没有更好的解决方案? 谢谢!

1 个答案:

答案 0 :(得分:1)

我不确定您的解决方案是否有效,因为当您查看JobsPlugin调用时,它会在每个作业执行结束时重新计算Job下一个计划执行日期。

这是我的解决方案,我重新创建一个JobScheduler类,以便能够根据我的工作的cron属性计算作业执行日期。由于可见性规则,我不得不重新声明一些作业属性。

所以我的工作班是

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属性定义的实例,并且此实例不会在最后重新安排itselft