scala - Play 2.4 : Schedule a recurring task at app startup with dependency injection

标签 scala playframework playframework-2.0 akka

我需要在应用程序启动时安排一个循环任务,任务本身非常简单,只需向应用程序发送一个即发即弃的 HTTP 调用即可。我不是游戏专家,我认为最简单的解决方案是在 Global.onStartplay.api.libs.concurrent.Akka.system.schedule。从 Play 2.4 开始,Global 配置已被弃用,取而代之的是新的 Guice DI。破解来自 DI documentation 的建议我无法为这个问题想出一个好的解决方案。我设法得到的最好的是在 GuiceApplicationLoader 之上编写一个包装器调用 BuiltInComponentsFromContext 的自定义实现,但在这种情况下我不能使用注入(inject)来获取 WSClient。用 Play 2.4 重写这样的东西的最佳方法是什么:

object Global extends GlobalSettings {
  override def onStart(app: Application) = {
    Akka.system.schedule(2.hours, 2.hours, theTask)
  }
}

最佳答案

更新:Play 2.6 现在有更好的记录:https://www.playframework.com/documentation/2.6.x/ScheduledTasks


你可以通过创建一个这样的模块来解决这个问题(注意代码注释):

package tasks

import javax.inject.{Singleton, Inject}

import akka.actor.ActorSystem
import com.google.inject.AbstractModule

import play.api.inject.ApplicationLifecycle

// Using the default ExecutionContext, but you can configure
// your own as described here:
// https://www.playframework.com/documentation/2.4.x/ThreadPools
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
import scala.concurrent.duration._

class MyRecurrentTaskModule extends AbstractModule {
  override def configure() = {
    // binding the RecurrentTask as a eager singleton will force
    // its initialization even if RecurrentTask is not injected in
    // any other object. In other words, it will starts with when
    // your application starts.
    bind(classOf[RecurrentTask]).asEagerSingleton()
  }
}

@Singleton
class RecurrentTask @Inject() (actorSystem: ActorSystem, lifecycle: ApplicationLifecycle) {

  // Just scheduling your task using the injected ActorSystem
  actorSystem.scheduler.schedule(1.second, 1.second) {
    println("I'm running...")
  }

  // This is necessary to avoid thread leaks, specially if you are
  // using a custom ExecutionContext
  lifecycle.addStopHook{ () =>
    Future.successful(actorSystem.shutdown())
  }

}

之后,您必须启用此模块,在您的 conf/application.conf 文件中添加以下行:

play.modules.enabled += "tasks.MyRecurrentTaskModule"

然后,只需启动您的应用程序,向它发出请求,然后就会看到计划任务每​​秒运行一次。

引用资料:

  1. Understanding Play thread pools
  2. Play Runtime Dependency Injection for Scala
  3. Integrating with Akka

相关问题:

  1. How to correctly schedule task in Play Framework 2.4.2 scala?
  2. Was asynchronous jobs removed from the Play framework? What is a better alternative?

关于scala - Play 2.4 : Schedule a recurring task at app startup with dependency injection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34799369/

相关文章:

scala - 当字段不完整时用 Circe 解码 Json

scala - Playframework 2.0 中用于身份验证和授权的 LDAP

Play 2.0 找不到 MySQL 驱动程序

java - 加载 Podcast 音频导致 Java 中出现 OutOfMemoryError

java - Japid 中 @Html 的替代品

c++ - Scala 和 C++11 的类型推断有什么区别?

scala - 在 sbt 中与 2.10.0 交叉构建

database - 在Slick中,使用Table[T]需要什么导入?

java - Play框架目标目录中的类被编译成什么?

mysql - Play framework 2.0.1 不断尝试进化错误的数据库类型