scala – 在系统启动时调度重复的actor Play 2.4.3
我最近开始使用
Scala和Play Framework,刚刚升级了我一直致力于Play 2.4.3的服务.我的最终目标是创建一个夜间进程,在我的播放应用程序中启动一个服务方法,以便通过方法调用来调度事件,我目前正在调用一个Actor.
我有一个基本的想法,通过覆盖onStart的Global.scala文件工作,但后来我看到了关于摆脱使用GlobalSettings(https://www.playframework.com/documentation/2.4.x/GlobalSettings)的播放文档,并一直试图将其转移到注入依赖方法. 以下是我到目前为止拼凑的内容: 模块代码: import javax.inject._ import com.myOrganization.myPackage.Actors.ScheduleActor import play.api.libs.concurrent.AkkaGuiceSupport import play.libs.Akka import play.api.libs.concurrent.Execution.Implicits.defaultContext import akka.actor.{ActorRef,ActorSystem} import scala.concurrent.duration._ import play.Application import com.google.inject.AbstractModule @Singleton class NightlyEvalSchedulerStartup @Inject()(system: ActorSystem,@Named("ScheduleActor") scheduleActor: ActorRef) { Akka.system.scheduler.schedule(10.seconds,20.seconds,scheduleActor,"ScheduleActor") } class ScheduleModule extends AbstractModule with AkkaGuiceSupport { def configure() = { bindActor[ScheduleActor]("ScheduleActor") bind(classOf[NightlyEvalSchedulerStartup]).asEagerSingleton } } 演员班: import akka.actor.{Actor,Props} import com.myOrganization.myPackage.services.MySchedulingService object ScheduleActor { def props = Props[ScheduleActor] class updateSchedules } class ScheduleActor extends Actor { val MySchedulingService: MySchedulingService = new MySchedulingService def receive = { case "runScheduler" => MySchedulingService.nightlyScheduledUpdate() } } Application.conf play.modules.enabled += "com.myOrganization.myPackage.modules.ScheduleModule" 该服务调用一个主要基于scala逻辑代码和Anorm数据库交互的方法. 每次我尝试使用激活器启动(或运行,一旦收到Http请求)启动服务,我会收到以下错误: Oops,cannot start the server. com.google.inject.CreationException: Unable to create injector,see the following errors: 1) Error injecting constructor,java.lang.RuntimeException: There is no started application 我尝试用简单的println()替换Aka.system.scheduler …片段来运行相同的代码,一切似乎工作正常,这意味着服务启动了,我在控制台上看到了我的消息.所以我猜我有一些依赖,我为Akka调度程序丢失了导致它爆炸的依赖.你能提出的任何建议都会很棒,我一整天都在反对这一点. 编辑(每个请求解决的代码): 模块代码,附加一些代码,用于第二天晚上3点的粗略估计.这可能会改变这一行,但它现在有效: package com.myOrganization.performanceManagement.modules import com.myOrganization.performanceManagement.Actors.ScheduleActor import com.myOrganization.performanceManagement.Actors.ScheduleActor.nightlySchedule import org.joda.time.{Seconds,LocalDate,LocalTime,LocalDateTime} import play.api.libs.concurrent.AkkaGuiceSupport import play.api.libs.concurrent.Execution.Implicits.defaultContext import akka.actor.{ActorRef,ActorSystem} import scala.concurrent.duration.{FiniteDuration,SECONDS,HOURS } import org.joda.time._ import com.google.inject.{Inject,Singleton,AbstractModule} import com.google.inject.name.Named class ScheduleModule extends AbstractModule with AkkaGuiceSupport { override def configure() = { bindActor[ScheduleActor]("ScheduleActor") bind(classOf[NightlyEvalSchedulerStartup]).asEagerSingleton() } } @Singleton class NightlyEvalSchedulerStartup @Inject()(system: ActorSystem,@Named("ScheduleActor") scheduleActor: ActorRef) { //Calculate initial delay to 3am the next day. val currentTime: DateTime = DateTime.now val targetDateTime = currentTime.plusDays(1).withTimeAtStartOfDay() //Account for Daylight savings to an extent,not mandatory that it starts at 3am,just after midnight. val initialDelaySeconds = targetDateTime.getHourOfDay match { case 0 => new Duration(currentTime,targetDateTime.plusHours(3)).getStandardSeconds case 1 => new Duration(currentTime,targetDateTime.plusHours(2)).getStandardSeconds } //Schedule first actor firing to occur at calculated delay and then every 24 hours. system.scheduler.schedule(FiniteDuration(initialDelaySeconds,SECONDS),FiniteDuration(24,HOURS),nightlySchedule) } 演员: package com.myOrganization.performanceManagement.Actors import akka.actor.{ActorSystem,Actor} import com.google.inject.Inject import com.myOrganization.performanceManagement.services.PMEvalSchedulingService object ScheduleActor { case object nightlySchedule } class ScheduleActor @Inject() (actorSystem: ActorSystem) extends Actor { val pMEvalSchedulingService: PMEvalSchedulingService = new PMEvalSchedulingService override def receive: Receive = { case nightlySchedule => println("Called the scheduler") pMEvalSchedulingService.nightlyScheduledEvaluationsUpdate() } } 解决方法
在我的情况下,最大的问题最终是当在NightlyEvalSchedulerStartup()中调度actor调用时,我调用了Akka.system …这导致系统在应用程序存在之前实例化新的AkkaSystem.通过删除akk系统来表示已经准备好的注入依赖性.希望这有助于未来的人!
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |