玩!框架:我可以重新安排工作时间吗? [英] Play! framework: can I reschedule the job?

查看:104
本文介绍了玩!框架:我可以重新安排工作时间吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


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


I'm using Play! framwork of version 1.2.4
In my application, I have implemented a number of scheduled jobs (descendants of play.jobs.Job).

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

Can I change the schedule of these jobs at runtime?

乍一看,Play中的工作安排!是通过play.jobs.JobsPlugin完成的,而play.jobs.JobsPlugin则使用JDK的java.util.concurrent.ScheduledThreadPoolExecutor实例,该实例公开公开.到目前为止,我想出了以下方法:当需要更改时间表时,我只需遍历执行者的预定工作,取消需要重新计划并计划同一工作(更准确地说,同一班级的工作)的工作即可.新设置.像这样:

At first glance, the job scheduling in Play! is done via play.jobs.JobsPlugin, which in turn uses JDK's java.util.concurrent.ScheduledThreadPoolExecutor instance which is publicly exposed. So far I came up with following approach: when it's the moment to change schedule, I simply iterate over executor' scheduled jobs, cancel one which I need to reschedule and schedule the same job (more precisely, the job of the same class) with new settings. Something like this:

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

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

Are there any better solutions? Thanks!

推荐答案

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

I am not sure your solution works because when you look at JobsPlugin call, it recalculates Job next planned execution date at the end of each job execution.

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

Here is my solution, I recreate a JobScheduler class to be able to calculate job execution date based on a cron attribute of my job. I had to redeclare some jobs attributes because of visibility rules.

所以我的工作是

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

我的调度程序类是 打包作业;

And my scheduler class is package jobs;

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小时.

With this code, you can call JobScheduler.scheduleMyJob to change the scheduling of the job by passing the right scheduling expression : 0 0 2 * * ? for every 2 hours.

当作业终止时,_finally方法将重新调用scheduleForCRON方法,该方法将设置新的调度时间.

When the job terminates, the _finally method will recall the scheduleForCRON method which set the new scheduling time.

如果要强制执行作业(例如,通过gui按钮),则可以创建一个不带cron属性定义的实例,并且该实例不会在最后自行重新安排时间

If you want to force execution of the job, for example through a gui button, you can create an instance without cron attribute define and this instance won't reschedule itselft at the end

这篇关于玩!框架:我可以重新安排工作时间吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆