【问题标题】:Scala Play 2.4 run akka scheduler service on Application startScala Play 2.4 在应用程序启动时运行 akka 调度程序服务
【发布时间】:2016-01-29 22:07:38
【问题描述】:

我想使用 Akka 调度程序在我的 Play 应用程序中执行一些 cron 作业。

自 Play 2.4 起不推荐使用 GlobalSettings。任何人都有一些关于如何做到这一点的示例代码?

即使我尝试了 Play 文档中的简单代码,它仍然无法正常工作。

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"

为什么我无法打印日志消息?

如何在应用程序启动时使用 Akka?

【问题讨论】:

  • 您确定您的自定义应用程序加载器正在用于引导应用程序吗?如果是这样,“开始”某事的最简单方法可能是 'bind[MyActor].toSelf.eagerly()'
  • 我只是从 Play doc 复制这段代码,我仍然不知道这样做的正确方法是什么?我什至尝试了 GlobalSettings,但仍然无法正常工作。
  • 我假设 play.application.loader=xxx 在您的 application.conf 中并指向您的应用程序加载器?
  • 是的。即使这样,仍然无法记录消息。
  • 如果你在开发模式下启动它,直到收到第一个请求它才会真正启动。我不确定,但也许这就是原因。

标签: scala playframework akka


【解决方案1】:

这是在我的应用程序中的操作方式:

首先定义一个 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())
  }
}

然后用 Akka 魔法实现 Scheduled

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

创建一个模块来急切地启动预定的东西

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

确保您的配置指定了 ScheduledModule。

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

瞧,当你的 play 2.4 应用启动时,你有一个工作计划任务 =)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多