aivaldi
aivaldi

Reputation: 67

Play 2.4.x Akka scheduler with application context

I'm trying to create a scheduler in play framework 2.4.x. I was able to create the scheduler, but can't configure the current application environment.

Basically, the scheduler should execute a controller method or call an URL.

So far I got this:

object Global extends GlobalSettings {

  override def onStart(app: Application) {
    System.out.println("App Started");
    import play.api.Play.current
    var delayInSeconds: Long = 0l;

    var c: Calendar = Calendar.getInstance();
    c.set(Calendar.HOUR_OF_DAY, current.configuration.getInt("application.execution.hour").getOrElse(8))
    c.set(Calendar.MINUTE, current.configuration.getInt("application.execution.min").getOrElse(0))
    c.set(Calendar.SECOND, 0);

    var plannedStart: Date = c.getTime();
    var now: Date = new Date();
    var nextRun: Date = null;
    if (now.after(plannedStart)) {
      c.add(Calendar.DAY_OF_WEEK, 1);
      nextRun = c.getTime();
    } else {
      nextRun = c.getTime();
    }
    delayInSeconds = (nextRun.getTime() - now.getTime()) / 1000; //To convert milliseconds to seconds.

    var delay: FiniteDuration = Duration(delayInSeconds, TimeUnit.SECONDS);
    var frequency: FiniteDuration = Duration(1, TimeUnit.DAYS);

    val schedulerActor = Akka.system(app).actorOf(Props[SchedulerActor], name = "schedulerActor")

    Akka.system(app).scheduler.schedule(delay, frequency, schedulerActor, Scheduler);
  }
}

case object Scheduler

class SchedulerActor extends Actor {

  def receive = {
    case Scheduler => executeSchedulerWorkflows
  }

  def executeSchedulerWorkflows = {

  }
}

Inside def executeSchedulerWorkflows I'd like to do something like:

def executeSchedulerWorkflows = {
    WS.client(url)
}

With WS injected. How to do that?

Upvotes: 0

Views: 179

Answers (1)

caeus
caeus

Reputation: 3716

You can do it by not doing it on the GlobalSettings (it's deprecated). Usually I do as follows:

  1. Create a Module

    class YourModule extends Module {
      override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = 
     Seq(bind[Init].toSelf.eagerly())
     }
    

Note: as you can see, there's a binding to Init...

  1. Create that Init class

     class Init @Inject()(application: Application, actorSystem: ActorSystem//Here you can inject whatever you want) {
    
     //TODO //Here you create the actor with all it's dependencies
    
     // or use directly the scheduler of the actorSystem
     actorSystem.scheduler.schedule(0.seconds,1.day){
    
         //Your stuff
    
     }
    

    }

  2. Register that module

     play.modules.enabled += "somepackage.YourModule"
    

Upvotes: 1

Related Questions