2016-07-04 13 views
1

我想在Play 2.5中创建一个预定的任务。我发现了一些与此主题相关的资源,但没有一个用于Play 2.5。我发现this resource与我正在寻找的东西有关,它看起来不错。在同一链接上也有一个从2.4到2.5的迁移指南。用scala创建一个预定的任务2.5

旧版本的示例使用GlobalSettings作为基础,但在2.5中已弃用此示例。迁移指南很重要,因为它说我们应该使用依赖注入来代替扩展这个特性。我不知道该怎么做。

你能给我一些指导吗?

+0

请参阅:http://stackoverflow.com/a/34803018/4600。 Play 2.5基本上是一样的。 – marcospereira

回答

5

你需要运行sheduled任务阿卡演员里面:

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" 
+0

对我来说,这只能在当地不幸运行。当我用'sbt stage'打包应用程序并部署到服务器时,它不会启动:'糟糕,无法启动服务器。无法加载模块[[...]由...引发:java.lang.ClassNotFoundException:modules.JobModule'。我错过了什么吗?谢谢你的帮助。 – Nick

+0

我测试它只与sbt本地包装商建立的软件包,它像一个魅力。我会在周末考察你的问题。 – mgosk

+0

您的解决方案的确可以在生产中使用。 Azure的自动部署似乎出了问题(我讨厌它)。谢谢!! – Nick

0

如果你不想用阿卡,您可以使用Java:

  • ScheduledFuture
  • ScheduledExecutorService的

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"