玩! 框架:我可以重新安排工作?(Play! framework: can I reschedu

2019-10-17 05:46发布


我使用的游戏! 1.2.4版本framwork
在我的应用程序,我已经实现了一些计划作业(后裔play.jobs.Job )。

我可以在运行时更改这些工作的时间表?

我自己的调查结果

乍一看,作业调度在玩游戏! 通过完成play.jobs.JobsPlugin ,又使用JDK的java.util.concurrent.ScheduledThreadPoolExecutor被公开曝光实例。 到目前为止,我想出了以下方法:当它改变时间表的那一刻,我只是遍历执行”安排的作业,取消一个,我需要重新安排和调度在相同的工作(更确切地说,是同一类的工作)与新的设置。 事情是这样的:

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;
    }
}

是否有更好的解决方案? 谢谢!

Answer 1:

我不知道您的解决方案工程,因为当你在看JobsPlugin调用,它在每个作业执行结束时重新计算工作下一计划的执行日期。

这里是我的解决方案,我重新创建的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 2 * *? 每2个小时。

当作业结束时,_finally方法都会想起scheduleForCRON方法,设置新的调度时间。

如果你想通过GUI按钮强制工作的执行,例如,你可以创建一个没有属性的cron定义一个实例,并在年底这种情况下不会重新安排itselft



文章来源: Play! framework: can I reschedule the job?