How to create a cron job in Play Framework

I’m creating a simple cron job that run a task in a specific time (for example 3AM) with Play Framework 2.6.x.
But now I’m stucking in a simple schedule task:

I created an Actor:

package actors;

import akka.actor.UntypedActor;
import org.slf4j.LoggerFactory;

public class DoSomethingActor extends UntypedActor {
    private static final org.slf4j.Logger log = LoggerFactory.getLogger(DoSomethingActor.class);

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

    }

}

Then I created a Schedule class that call Actor each time I’ve set:

package tasks;

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

Finally, I bind these class in a Module class:

package modules;

import actors.DoSomethingActor;
import com.google.inject.AbstractModule;

import play.libs.akka.AkkaGuiceSupport;
import tasks.DoSomethingScheduler;

public class SchedulerModule extends AbstractModule implements AkkaGuiceSupport{

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

}

After these things, I run the application but it doesn’t work as I expected. I expected it shows a logging every 1 SECOND but there is nothing happen.

Could you please help me to fix it?
Thank you so much!

1 Like

Have you registered your module in the application.conf ?

1 Like

and btw. you might want to take a look into


instead of building your own cron-like scheduler

Yes, I registered. I have a source code demo on my Github. Could you please help me to check it?


Thank you.

in your application.conf you write
play.modules.enabled += "services.ServiceModule"
while it should be
play.modules.enabled += "modules.SchedulerModule"

1 Like

I changed the config but I there is nothing is logged as I expected.

put println()s everywhere to verify that your module is loaded, then verify that your actor and service is created etc.
also note, that your module etc. will only be loaded once you send a first http request (in dev mode)

1 Like

By the way, there are documentation about how to do it here:

https://www.playframework.com/documentation/2.7.x/ScheduledTasks

Best.

2 Likes

You’re right. In dev mode, I have to send a HTTP request to the Play Application, only after that, the application runs the scheduled job.
Does it work without send a HTTP request when I deploy it in production mode?

Yes,

You can confirm that by running sbt testProd instead of run. :slight_smile:

Best.

1 Like

Does it work without send a HTTP request when I deploy it in production mode?

yes, in production mode all actors etc. startup immediately, so also your scheduler.

2 Likes