使用预定的Akka Runnable调用Controller DBAction(在Scala / Play 2.2中)

时间:2013-10-31 03:53:32

标签: scala playframework akka playframework-2.2 play-slick

当我的Play 2.2应用程序启动时,我正在尝试安排Akka作业。

这是最简单的形式,这就是我的代码:

import play.api.Application
import play.api.Play.current
import play.api.GlobalSettings
import play.api.Logger
import play.api.db.DB
import scala.concurrent.duration._

import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Execution.Implicits._

import scala.slick.driver.MySQLDriver.simple._

object Global extends GlobalSettings {
  override def onStart(app: Application) {
    lazy val database = Database.forDataSource(DB.getDataSource())

    scheduleTheThing(app)
  }

  private def scheduleTheThing(app: Application) {
    Akka.system.scheduler.scheduleOnce(1.minute, new Runnable {
      override def run() {
        Logger.info("running the thing!")
        controllers.Application.runTheThing
      }
    })
  }
}

正如您所看到的,我正在创建一个新的Runnable,它将在应用程序启动后1分钟执行。 Logger.info("Running the thing!")被执行得很好......我能够看到“正在运行的东西!”在启动服务器1分钟后的应用程序日志中。但是,controllers.Application.runTheThing似乎没有被调用:

object Application extends Controller {
  def runTheThing = DBAction {
    implicit session => {
      Logger.info("It's happening!")
      DBThing.doSomeDBStuff()
    }
  }
  // ...
}

我的“它正在发生!” log语句永远不会出现,而DBThing.doSomeDBStuff()应该做的事情永远不会发生。奇怪的是控制台或日志文件中没有错误。

如何从预定的runnable调用控制器DBAction?或者我应该如何修改我的调度程序以使其有效?非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:3)

调用action方法只会返回一个Action实例,为了实际执行它,你必须调用它,就像正常播放请求一样。我建议将其解压缩到非控制器代码,然后从计划任务中调用它。