Akka Scala演员预定的消息似乎没有开火

时间:2014-04-08 14:32:55

标签: scala akka

在尝试使用Akka演员时,我编写了一个用例并没有按预期工作。我已经定义了一个接收MyActor消息的演员"start"。此消息启动一个调度程序,该调度程序应该每隔"request"将消息self中继到1 second。这是代码:

import akka.actor._
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.pattern.gracefulStop
import scala.concurrent.ExecutionContext.Implicits.global

object ScheduledActors {

  def main(args: Array[String]) {

    implicit val system = ActorSystem("ScheduledActors")
    val admin = system.actorOf(Props[MyActor], name = "my-actor")

    admin ! "start"

    val adminFuture = gracefulStop(admin, 2 minutes)
    Await.result(adminFuture, 2 minutes)
  }

class MyActor extends Actor {

  var cancellableOption: Option[Cancellable] = None

  def receive = {

    case "start" =>
      println("start")

      cancellableOption =
        Some(context.system.scheduler.schedule(0 seconds, 1 second) { self ! "request" })

    case "request" =>
      println("request")

    case "stop" =>
      println("stop")

      cancellableOption match {
        case None => // no-op
        case Some(v) => v.cancel()
      }

      context.stop(self)
    }
  }
}

我尝试了一些变种。将schedule方法变体与明确的ActorRefmessage结合使用。 E.g:

schedule(initialDelay: Duration, frequency: Duration, receiver: ActorRef, message: Any): Cancellable

在每种情况下,演员都不会收到"request"消息。这个块肯定被调用,因为我已经使用println语句进行了验证,作为一个完整性检查。但交付是不行的。

这使我认为self引用在此上下文中实际执行时可能不会提供相同的上下文(例如,ForkJoinPool调用)。 Akka文档确实警告不要在调度调用的上下文中使用不稳定的引用。但是self作为接收者被明确引用为reasonable alternative

此时我在这里有点不知所措。任何帮助是极大的赞赏。

1 个答案:

答案 0 :(得分:1)

这是因为演员已被终止。在运行时,您应该看到记录死信,例如:

[INFO] [04/08/2014 17:05:03.903] [ScheduledActors-akka.actor.default-dispatcher-2] [akka:// ScheduledActors / user / my-actor]消息[java.lang。字符串]从Actor [akka:// ScheduledActors / user / my-actor#-1824493491]到Actor [akka:// ScheduledActors / user / my-actor#-1824493491]未送达。 [1]遇到死信。可以使用配置设置关闭或调整此日志记录' akka.log-dead-letters'和' akka.log-dead-letters-during-shutdown'。

GracefulStop不了解您已完成的计划并停止该actor,因为邮箱为空。 如果要将main方法更改为以下内容,则应该看到消息:

implicit val system = ActorSystem("ScheduledActors")
val admin = system.actorOf(Props[MyActor], name = "my-actor")

admin ! "start"

Thread.sleep(5000)
admin ! "stop"