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
How to schedule task daily + onStart() in Play 2.0.4?
提问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 initialDelay
and also set frequency
to 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);
}
}