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

后端 未结 3 1773
不思量自难忘°
不思量自难忘° 2020-11-30 05:18

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 req

相关标签:
3条回答
  • 2020-11-30 05:39

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 05:44

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-30 05:45

    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);
    }
    
    }
    
    0 讨论(0)
提交回复
热议问题