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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14706300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:06:21  来源:igfitidea点击:

How to schedule task daily + onStart() in Play 2.0.4?

javaplayframework-2.0akkascheduler

提问by gabby

I need to execute a piece of code 1 time everyday in playframework2.0.4 when I try to do with the class extends GlobalSettings it works. But it works for every instance requesting. I want it works when server starts and does its duty everyday 1 time.

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

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

And this is my controller where start the class above

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

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 "));

}
}

回答by biesior

Scheduler tasks should be placed only in Global class. Create two tasks, schedule only once first with initialDelay= 0 milliseconds.

调度程序任务应该只放在 Global 类中。创建两个任务,首先只调度一次,时间initialDelay= 0 毫秒。

For the second task, you need to calculate seconds between current DateTime and next planned occurrence (ie. tomorrow at 8:00 o'clock) using common date/time classes, then set this difference as initialDelayand also set frequencyto 24 hours.

对于第二个任务,您需要使用常见的日期/时间类计算当前 DateTime 和下一个计划事件(即明天 8:00 点)之间的秒数,然后将此差异设置为initialDelay并设置frequency为 24 小时。

In result, it will start at the application start and will schedule the task for execution each day at required hour.

因此,它将在应用程序启动时启动,并将安排每天在所需时间执行的任务。

Edit

编辑

There's complete sample, (save/edit the class: /app/Global.java):

有完整的示例,(保存/编辑类:)/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;
    }
}

回答by Ilja S.

Here is my solution which is lighter and supports cron expressions for scheduling. In this example, the scheduler will run everyday at 10:00 AM.

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

Following in your Global class:

在您的 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);
    }
}

回答by Nirojan Selvanathan

This can be done using the Global Class, and over riding the onstart method. https://www.playframework.com/documentation/2.5.x/JavaGlobal

这可以使用全局类来完成,并超越 onstart 方法。https://www.playframework.com/documentation/2.5.x/JavaGlobal

The code below prints the JVM stats in 10 Mins Intervals. The time duration can be configured in order to suit the need.

下面的代码以 10 分钟的间隔打印 JVM 统计信息。可以配置持续时间以满足需要。

An abstract view of the coding is given below. Hope this help

下面给出了编码的抽象视图。希望这有帮助

public class Global extends GlobalSettings {

private Cancellable scheduler;

@Override
public void onStart(Application application) {
    int timeDelayFromAppStartToLogFirstLogInMs = 0;
    int timeGapBetweenMemoryLogsInMinutes = 10;
    scheduler = Akka.system().scheduler().schedule(Duration.create(timeDelayFromAppStartToLogFirstLogInMs, TimeUnit.MILLISECONDS),
            Duration.create(timeGapBetweenMemoryLogsInMinutes, TimeUnit.MINUTES),
            new Runnable() {
                @Override
                public void run() {
                    System.out.println("Cron Job");
                    // Call a function (to print JVM stats)
                }
            },
            Akka.system().dispatcher());
    super.onStart(application);
}

@Override
public void onStop(Application app) {
    scheduler.cancel();
    super.onStop(app);
}

}