我想在Play 2.5中创建一个计划任务。我找到了一些与此主题相关的资源,但没有一个是针对Play 2.5的。我发现this resource与我正在寻找的相关,看起来不错。同样在同一链接上有一个从2.4到2.5的迁移指南。
旧版本的示例使用GlobalSettings
作为基础,但在2.5中已弃用。迁移指南很重要,因为它说我们应该使用依赖注入而不是扩展这个特性。我不知道该怎么做。
你能给我一些指导吗?
答案 0 :(得分:8)
你需要在Akka Actor中运行已经完成的任务:
<强> SchedulerActor.scala 强>
package scheduler
import javax.inject.{Inject, Singleton}
import akka.actor.Actor
import org.joda.time.DateTime
import play.api.Logger
import scala.concurrent.ExecutionContext
@Singleton
class SchedulerActor @Inject()()(implicit ec: ExecutionContext) extends Actor {
override def receive: Receive = {
case _ =>
// your job here
}
}
<强> Scheduler.scala 强>
package scheduler
import javax.inject.{Inject, Named}
import akka.actor.{ActorRef, ActorSystem}
import play.api.{Configuration, Logger}
import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
class Scheduler @Inject() (val system: ActorSystem, @Named("scheduler-actor") val schedulerActor: ActorRef, configuration: Configuration)(implicit ec: ExecutionContext) {
val frequency = configuration.getInt("frequency").get
var actor = system.scheduler.schedule(
0.microseconds, frequency.seconds, schedulerActor, "update")
}
<强> JobModule.scala 强>
package modules
import com.google.inject.AbstractModule
import play.api.libs.concurrent.AkkaGuiceSupport
import scheduler.{Scheduler, SchedulerActor}
class JobModule extends AbstractModule with AkkaGuiceSupport {
def configure() = {
bindActor[SchedulerActor]("scheduler-actor")
bind(classOf[Scheduler]).asEagerSingleton()
}
}
<强> application.conf 强>
play.modules.enabled += "modules.JobModule"
答案 1 :(得分:0)
如果您不想使用akka,可以使用java:
<强> DemoDaemon.scala:强>
import java.util.concurrent.{Executors, ScheduledFuture, TimeUnit}
import javax.inject._
import play.Configuration
import scala.util.Try
class DemoDaemon @Inject() (conf: Configuration) {
val isEnabled = conf.getBoolean("daemon.enabled")
val delay = conf.getLong("daemon.delay")
private var scheduledTaskOption : Option[ScheduledFuture[_]] = None
def task(): Unit = {
Try {
println("doSomething")
} recover {
case e: Throwable => println(e.getMessage)
}
}
def start(): Unit = {
if (isEnabled) {
val executor = Executors.newScheduledThreadPool(1)
scheduledTaskOption = Some(
executor.scheduleAtFixedRate(
new Runnable {
override def run() = task()
},
delay, delay, TimeUnit.SECONDS
)
)
} else {
println("not enabled")
}
}
def stop(): Unit = {
scheduledTaskOption match {
case Some(scheduledTask) =>
println("Canceling task")
val mayInterruptIfRunning = false
scheduledTask.cancel(mayInterruptIfRunning)
case None => println("Stopped but was never started")
}
}
}
<强> DaemonService.scala 强>
import javax.inject.Inject
import play.api.inject.ApplicationLifecycle
import scala.concurrent.Future
class DaemonService @Inject() (appLifecycle: ApplicationLifecycle, daemon: DemoDaemon) {
daemon.start()
appLifecycle.addStopHook{ () =>
Future.successful(daemon.stop())
}
}
<强> JobModule.scala 强>
import com.google.inject.AbstractModule
class JobModule extends AbstractModule {
def configure(): Unit = {
bind(classOf[DaemonService]).asEagerSingleton()
}
}
<强> application.conf 强>
daemon.enabled = true
daemon.delay = 10
play.modules.enabled += "com.demo.daemon.JobModule"