0

I want to use Akka scheduler to do some cron jobs in my Play application.

Since Play 2.4 GlobalSettings is not recommended. Anyone has some sample code on how to do that?

Even I tried the simple code from Play docs and it still not working.

class CustomApplicationLoader extends GuiceApplicationLoader() {
  val logger: Logger = Logger(this.getClass)

  override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {
    logger.info("start")
    val extra = Configuration("a" -> 1)
    initialBuilder
      .in(context.environment)
      .loadConfig(extra ++ context.initialConfiguration)
      .overrides(overrides(context): _*)
  }
}

play.application.loader = "com.xxx.CustomApplicationLoader"

Why I can't get the logging message to print?

How I can use Akka on Application start?

ttt
  • 3,934
  • 8
  • 46
  • 85
  • Are you sure you custom application loader is being used to bootstrap the applicaiton? If so, the simplest way to 'start' something is probably 'bind[MyActor].toSelf.eagerly()' – rethab Jan 28 '16 at 06:29
  • I just copy this code from Play doc, I still have no idea what is the correct way doing that? I even tried GlobalSettings, and still not working. – ttt Jan 28 '16 at 06:36
  • I'm assuming the play.application.loader=xxx is in your application.conf and points to your application loader? – rethab Jan 28 '16 at 07:43
  • yes. Even that, still can't log the messages. – ttt Jan 28 '16 at 08:06
  • If you are starting it in Dev mode it's not actually started untill receives first request. I'm not sure, but, perhaps, this is the reason. – Yury Sukhoverkhov Jan 28 '16 at 08:13
  • I even tried to hit some other request. But still not working – ttt Jan 28 '16 at 08:26
  • Possible duplicate of [Start a recurring task on the Play 2.4 app launch with new DI](http://stackoverflow.com/questions/34799369/start-a-recurring-task-on-the-play-2-4-app-launch-with-new-di) – marcospereira Jan 28 '16 at 13:20

1 Answers1

2

This is how do it in my app:

Start of by defining a trait Scheduled.

package scheduled

import akka.actor.Cancellable

trait Scheduled {

  var cancellable: Option[Cancellable] = None

  val defaultInterval = 60
  val secondsToWait = {
    import scala.concurrent.duration._
    10 seconds
  }

  def start()
  def stop() = {
    cancellable.map(_.cancel())
  }
}

Then implement Scheduled with Akka magic

package scheduled

import akka.actor.ActorSystem
import play.api.{Configuration, Logger}
import com.google.inject.{Singleton, Inject}
import play.api.libs.concurrent.Execution.Implicits._

trait ScheduledWorker extends Scheduled

@Singleton
class ScheduledWorkerImpl @Inject()(
                                                  actorSystem: ActorSystem,
                                                  configuration: Configuration

                                                  ) extends ScheduledWorker {
  start()

  lazy val intervalKey = "worker.interval"
  lazy val jobEnabled = "worker.enabled"

  override def start(): Unit = {
    import scala.concurrent.duration._
    lazy val i = configuration.getInt(intervalKey).getOrElse(defaultInterval)
    lazy val isEnabled = Option(System.getProperty(jobEnabled)).getOrElse(
      configuration.getString(jobEnabled).getOrElse("false")
    ).equals("true")

    cancellable = isEnabled match {
      case true =>
        Some(
          actorSystem.scheduler.schedule(0 seconds, i minutes) {
            .. MAJOR COOL CODE!!! ;))) ...
          }
        )
      case _ => None
    }
  }
}

create a module to eagerly start the scheduled stuff

package modules

import play.api.{Configuration, Environment}
import play.api.inject.Module
import scheduled.{ScheduledWorker}

class ScheduledModule extends Module {

  def bindings(environment: Environment,
               configuration: Configuration) = Seq(
      bind[ScheduledWorker].to[ScheduledWorkerImpl].eagerly()
    )
}

make sure that your config specifies ScheduledModule.

play.modules.enabled += "modules.ScheduledModule"

And voila you have a working scheduled task when your play 2.4 app starts =)

jakob
  • 5,979
  • 7
  • 64
  • 103