Как планировать задачу ежедневно + onStart() в Play 2.0.4?
Мне нужно выполнить кусок кода 1 раз каждый день в playframework2.0.4, когда я пытаюсь сделать с классом extends GlobalSettings, он работает. Но он работает для каждого запроса. Я хочу, чтобы он работал, когда сервер запускается и выполняет свой долг каждый день 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());
}
});
}
}
И это мой контроллер, где запускают класс выше
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 "));
}
}
Ответы
Ответ 1
Задачи планировщика должны размещаться только в глобальном классе. Создайте две задачи, сначала заплатите только с initialDelay
= 0 миллисекунд.
Для второй задачи вам нужно вычислить секунды между текущей DateTime и следующим запланированным вводом (т.е. tommorow в 8:00 часов) с использованием общих классов даты и времени, затем установите эту разницу как initialDelay
, а также установите frequency
до 24 часов.
В результате он начнется при запуске приложения и будет планировать выполнение задачи каждый день в требуемый час.
Edit
Здесь полный образец, (сохраните/отредактируйте класс: /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;
}
}
Ответ 2
Вот мое решение, которое легче и поддерживает выражения cron для планирования. В этом примере планировщик будет работать каждый день в 10:00.
Следуя вашему глобальному классу:
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);
}
}
Ответ 3
Это можно сделать, используя глобальный класс, и вернемся к методу onstart. https://www.playframework.com/documentation/2.5.x/JavaGlobal
Приведенный ниже код печатает статистику JVM в интервалах 10 минут. Длительность времени может быть настроена для удовлетворения потребностей.
Ниже представлен абстрактный вид кодирования. Надеемся на эту помощь.
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);
}
}