Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

}
}
like image 325
gabby Avatar asked Feb 05 '13 11:02

gabby


People also ask

How do you schedule a task in Java?

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.


3 Answers

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;
    }
}
like image 128
biesior Avatar answered Sep 29 '22 19:09

biesior


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);
    }
}
like image 20
Ilja S. Avatar answered Sep 29 '22 18:09

Ilja S.


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

}
like image 29
Nirojan Selvanathan Avatar answered Sep 29 '22 18:09

Nirojan Selvanathan