如何在Play 2.0.4中每天安排任务+ onStart()?

gab*_*bby 15 java scheduler akka playframework-2.0

我需要每天在playframework2.0.4中执行一段代码,当我尝试使用类扩展GlobalSettings时它可以工作.但它适用于每个请求的实例.我希望它在服务器启动时起作用并且每天执行一次任务.

package controllers;
import java.util.concurrent.TimeUnit;
import akka.util.Duration;
import play.Application;
import play.GlobalSettings;
import play.libs.Akka;

public class ParserJobApp extends GlobalSettings{
@Override
public void onStart(Application app) {
    Akka.system().scheduler().schedule(Duration.create(0, TimeUnit.MILLISECONDS),Duration.create(6, TimeUnit.SECONDS), new Runnable() { 
        @Override
        public void run() {
            System.out.println("AAA ---    "+System.currentTimeMillis());
        }
    });
}
}
Run Code Online (Sandbox Code Playgroud)

这是我的控制器开始上面的课程

public class Application extends Controller {

public static Result index() { 
  ParserJobApp pr=new ParserJobApp();
  pr.onStart(null);
  System.out.println("sfsdfsdf");
return ok(index.render("Your new "));

}
}
Run Code Online (Sandbox Code Playgroud)

bie*_*ior 24

调度程序任务应仅放在Global类中.创建两个任务,首先调度一次initialDelay= 0毫秒.

对于第二个任务,您需要使用常用日期/时间类计算当前DateTime和下一个计划发生之间的秒数(即明天晚上8点),然后将此差值设置为initialDelay并且也设置frequency为24小时.

结果,它将在应用程序启动时开始,并将在每个所需的时间安排执行任务.

编辑

有完整的样本,(保存/编辑类:) /app/Global.java:

import akka.util.Duration;
import org.joda.time.DateTime;
import org.joda.time.Seconds;
import play.Application;
import play.GlobalSettings;
import play.Logger;
import play.libs.Akka;
import java.util.concurrent.TimeUnit;

public class Global extends GlobalSettings {

    @Override
    public void onStart(Application application) {


        Akka.system().scheduler().scheduleOnce(
                Duration.create(0, TimeUnit.MILLISECONDS),
                new Runnable() {
                    @Override
                    public void run() {
                        Logger.info("ON START ---    " + System.currentTimeMillis());
                    }
                }
        );

        Akka.system().scheduler().schedule(
                Duration.create(nextExecutionInSeconds(8, 0), TimeUnit.SECONDS),
                Duration.create(24, TimeUnit.HOURS),
                new Runnable() {
                    @Override
                    public void run() {
                        Logger.info("EVERY DAY AT 8:00 ---    " + System.currentTimeMillis());
                    }
                }
        );
    }

    public static int nextExecutionInSeconds(int hour, int minute){
        return Seconds.secondsBetween(
                new DateTime(),
                nextExecution(hour, minute)
        ).getSeconds();
    }

    public static DateTime nextExecution(int hour, int minute){
        DateTime next = new DateTime()
                .withHourOfDay(hour)
                .withMinuteOfHour(minute)
                .withSecondOfMinute(0)
                .withMillisOfSecond(0);

        return (next.isBeforeNow())
                ? next.plusHours(24)
                : next;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,这就是我的做法:可取消的调度程序= Akka.system().scheduler().schedule(....); 并创建:@Override public void onStop(应用程序应用程序){scheduler.cancel(); } (3认同)
  • 我在回答之后意识到:http://doc.akka.io/docs/akka/2.0/java/scheduler.html有一条评论:'_it必须在.close()上执行所有未完成的任务才能正确关闭所有dispatchers._',可能导致最后一次执行.如果你找不到任何解决方案,这对于新问题来说是个好主题(我对此感兴趣,但现在没有时间) (2认同)

Ilj*_* S. 16

这是我的解决方案,它更轻,支持用于调度的cron表达式.在此示例中,调度程序将在每天上午10:00运行.

在您的Global课程中关注:

private Cancellable scheduler;

@Override
public void onStart(Application application) {
    super.onStart(application); 
    schedule(); 
}

@Override
public void onStop(Application application) {
    //Stop the scheduler
    if (scheduler != null) {
        scheduler.cancel();
    }
}

private void schedule() {
    try {
        CronExpression e = new CronExpression("0 00 10 ? * *");
        Date nextValidTimeAfter = e.getNextValidTimeAfter(new Date());
        FiniteDuration d = Duration.create(
            nextValidTimeAfter.getTime() - System.currentTimeMillis(), 
            TimeUnit.MILLISECONDS);

        Logger.debug("Scheduling to run at "+nextValidTimeAfter);

        scheduler = Akka.system().scheduler().scheduleOnce(d, new Runnable() {

        @Override
        public void run() {
            Logger.debug("Ruuning scheduler");
            //Do your tasks here

            schedule(); //Schedule for next time

        }
        }, Akka.system().dispatcher());
    } catch (Exception e) {
        Logger.error("", e);
    }
}
Run Code Online (Sandbox Code Playgroud)