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.
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 "));
}
}
One of the methods in the Timer class is the void schedule(Timertask task, Date time) method. This method schedules the specified task for execution at the specified time. If the time is in the past, it schedules the task for immediate execution.
Scheduler tasks should be placed only in Global class. Create two tasks, schedule only once first with initialDelay
= 0 milliseconds.
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.
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
):
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;
}
}
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.
Following in your Global class:
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);
}
}
This can be done using the Global Class, and over riding the onstart method. 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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With