play framework 2.1 - 调度异步任务

时间:2012-11-20 03:13:42

标签: playframework-2.0 scheduled-tasks akka playframework-2.1

在Play的2.0.x文档中,您可以看到如何安排异步任务:

http://www.playframework.org/documentation/2.0.4/ScalaAkka

Akka.system.scheduler.schedule(0 seconds, 30 minutes, testActor, "tick")

你怎么能用最近的重新播放Play 2.1 ???

来实现同样的目标

整个akka API似乎已经改变了......

我查了一下:

https://github.com/playframework/Play20/wiki/Highlights https://github.com/playframework/Play20/wiki/Migration 并且 http://doc.akka.io/docs/akka/2.1.0-RC1/project/migration-guide-2.0.x-2.1.x.html

也在这里问:https://groups.google.com/d/topic/play-framework/7VcwNea6QlM/discussion

3 个答案:

答案 0 :(得分:20)

使用sample codeAkka API我做了快速测试,对我有用。

比较2.0.4和2.1RC1之间的代码我可以看到调度程序只有两个变化:

  1. 已取代导入

    // import akka.util.duration._
    import scala.concurrent.duration._
    
  2. 添加了导入:

    import play.api.libs.concurrent.Execution.Implicits._
    
  3. app/controllers/Application.scala

    package controllers
    
    import play.api._
    import play.api.mvc._
    import play.libs.Akka
    
    import akka.actor._
    import scala.concurrent.duration._
    import play.api.libs.concurrent.Execution.Implicits._
    
    object Application extends Controller {
    
      def index = Action {
    
        // say hello
        Logger.info("hello, index action started")
    
        val Tick = "tick"
        val Tack = "tack"
    
        val tickActor = Akka.system.actorOf(Props(new Actor {
          def receive = {
            case Tick => Logger.info("that still ticks!")
            case Tack => Logger.warn("... 7 seconds after start, only once")
          }
        }))
    
        // Repeat every 5 seconds, start 5 seconds after start
        Akka.system.scheduler.schedule(
          5 seconds,
          5 seconds,
          tickActor,
          Tick
        )
    
        // do only once, 7 seconds after start
        Akka.system.scheduler.scheduleOnce(7 seconds, tickActor, Tack)
    
        Ok(views.html.index("Your new application is ready."))
      }
    
    }
    

    修改

    Nota bene,正如我从Julien的小组帖子中看到的那样,仅足以导入defaultContext

    import play.api.libs.concurrent.Execution.Implicits.defaultContext
    

答案 1 :(得分:9)

biesior's answer很棒

但是,如果你不愿意,你不会通过一个演员。以下是使用优质旧java.lang.Runnable的相同答案:

Akka.system.scheduler.schedule(5 minutes, 5 minutes, new Runnable {
  def run() {
    Logger.info("that still ticks!")
  }
})
Akka.system.scheduler.scheduleOnce(7 minutes, new Runnable {
  def run() {
    Logger.warn("... 7 seconds after start, only once")
  }
})

答案 2 :(得分:2)

例如,每周六上午15点在java中运行任务:

DateTime now = new DateTime();

DateTime plannedStart = new DateTime()
    .withDayOfWeek(DateTimeConstants.SATURDAY)
    .withHourOfDay(15)
    .withMinuteOfHour(0)
    .withSecondOfMinute(0)
    .withMillisOfSecond(0);

DateTime nextRun = (now.isAfter(plannedStart))
    ? plannedStart.plusDays(7)
    : plannedStart;

Long nextRunInSeconds = (long) secondsBetween(now, nextRun).getSeconds();

Akka.system().scheduler().schedule(
    Duration.create(nextRunInSeconds, TimeUnit.SECONDS),
    Duration.create(7, TimeUnit.DAYS) ,
    new Runnable() {
        public void run() {
            Logger.info("-------------------------scheduler start : " + new DateTime());
        }
    },
    Akka.system().dispatcher()
);