mvee
mvee

Reputation: 293

Play 2.5 - Run a Java method at certain times of day (cron)

I'm working on a Play 2.5 app that needs to run a method at midday, 2pm, 4pm every day autonomously.

So far I have followed another answer on here which has got me most of the way. The application.conf file has been updated to look at the Module file, which binds to the OnStartup() method correctly.

I believe the issue is to do with the code in the OnStartup() method, I've included the code below - is this the correct way to get something to run at certain times of day?

package controllers;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.util.Calendar;


@Singleton
public class OnStartup {

    @Inject
    public OnStartup() {

        Calendar cal = Calendar.getInstance();

        String hour = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
        String minute = String.valueOf(cal.get(Calendar.MINUTE));

        String dateTime = hour + ":" + minute;
        String time = "12:00";
        String time1 = "14:00";
        String time2 = "16:00";

        if (dateTime.equals(time) || dateTime.equals(time1) || dateTime.equals(time2)){
            System.out.print(dateTime);
            myAmazingClass.doSomethingWonderful();
        }
    }
}

Upvotes: 0

Views: 903

Answers (1)

Ritesh Singh
Ritesh Singh

Reputation: 93

As per your approach you need three things Module,actor,and a scheduler.

Step1: Create Actor

import akka.actor.UntypedActor;
import play.Logger;

public class DoSomethingActor extends UntypedActor{

    @Override
    public void onReceive(final Object message) throws Throwable {
        Logger.info("Write your crone task or simply call your method here that perform your task"+message);

    }

}

Step2:Create scheduler

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Cancellable;
import scala.concurrent.duration.Duration;

@Singleton
public class DoSomethingScheduler {

    @Inject
    public DoSomethingScheduler(final ActorSystem system,
            @Named("do-something-actor") final ActorRef doSomethingActor) {
        final Cancellable scheduler;
        final int timeDelayFromAppStart = 0;
        final int timeGapInSeconds = 1; //Here you provide the time delay for every run
        system.scheduler().schedule(
                Duration.create(timeDelayFromAppStart, TimeUnit.MILLISECONDS), //Initial delay when system start
                Duration.create(timeGapInSeconds, TimeUnit.SECONDS),     //Frequency delay for next run
                doSomethingActor,
                "message for onreceive method of doSomethingActor",
                system.dispatcher(),
                null);
    }
}

Step3: Bind your scheduler and actor with module.

import com.google.inject.AbstractModule;

import play.libs.akka.AkkaGuiceSupport;

public class SchedulerModule extends AbstractModule implements AkkaGuiceSupport{

    @Override
    protected void configure() {
        this.bindActor(DoSomethingActor.class, "do-something-actor");
        this.bind(DoSomethingScheduler.class).asEagerSingleton();
    }

}

Step4: Configure your module in aaplication.conf

play.modules.enabled += "com.rits.modules.SchedulerModule"

Make sure that no need to worry about onStart module leave that as usual, this module is only serving your purpose of scheduling task.

Upvotes: 2

Related Questions