Hoe een taak dagelijks plannen + onStart() in Play 2.0.4?
Plannertaken mogen alleen in de Global-klasse worden geplaatst. Maak twee taken, plan slechts één keer eerst met initialDelay
=0 milliseconden.
Voor de tweede taak moet u seconden berekenen tussen de huidige DateTime en de volgende geplande gebeurtenis (d.w.z. morgen om 8:00 uur) met behulp van algemene datum-/tijdklassen, en dit verschil instellen op initialDelay
en stel ook frequency
. in tot 24 uur.
Het resultaat is dat het begint bij het starten van de toepassing en de taak elke dag op het gewenste uur voor uitvoering plant.
Bewerken
Er is een compleet voorbeeld, (bewaar/bewerk de klasse:/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;
}
}
Hier is mijn oplossing die lichter is en cron-expressies ondersteunt voor planning. In dit voorbeeld wordt de planner elke dag om 10:00 uur uitgevoerd.
Volgen in je wereldwijde klas:
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);
}
}
Dit kan worden gedaan met behulp van de Global Class en over de onstart-methode heen. https://www.playframework.com/documentation/2.5.x/JavaGlobal
De onderstaande code drukt de JVM-statistieken af in intervallen van 10 minuten. De tijdsduur kan worden geconfigureerd om aan de behoefte te voldoen.
Hieronder volgt een abstracte weergave van de codering. Ik hoop dat dit helpt
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);
}
}