发送多条消息时Akka死信

时间:2015-11-25 16:07:47

标签: akka

我是Akka的新手,在尝试与我的演员进行集成测试时遇到了一些问题。

我收到了一个'TalkerSocket'演员:

def receive = LoggingReceive {
case msg: JsValue =>
  log.info(msg.toString())

  (msg \ "type").asOpt[String] match {
    case Some("authenticate") =>
      println("authenticate")
    case None                 =>
      log.info("fail")
      out ! Json.obj("error" -> "You should specify a type")
    case t                    =>
      log.info("fail")
      out ! Json.obj("error" -> "You should specify a valid type")
  }

case _ =>
  log.info("fail")
  out ! Json.obj("error" -> "unknown message format")
}

我正在测试这样:

val platoId = StringStub.random(6)
val platoConnection = TestProbe()
val platoSocket = system.actorOf(TalkerSocket.props(platoId)(platoConnection.ref))

def authMessage(talkerId: String) = {
    Json.parse(
      s"""
        {
          "type" : "authenticate",
          "data" : {
            "user_id" : "$talkerId",
            "auth_token" : "not_used_yet"
          }
        }
        """.stripMargin)
}

当我这样做时:

platoSocket ! authMessage(platoId)

一切看起来都不错。

当我尝试发送两条消息时,例如:

platoSocket ! authMessage(platoId)
platoSocket ! authMessage(platoId)

我的第二个错误:

[INFO] [11/25/2015 16:56:49.225] [TypingSpecLol-akka.actor.default-dispatcher-4] [akka://TypingSpecLol/user/$a] Message [play.api.libs.json.JsObject] from Actor[akka://TypingSpecLol/system/testActor1#-94087043] to Actor[akka://TypingSpecLol/user/$a#754865806] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

为了好奇,我尝试:

platoSocket ! authMessage(platoId)
Thread.sleep(1000)
platoSocket ! authMessage(platoId)

我没有收到Dead Letter的任何错误消息。

有人知道这里发生了什么吗?有没有办法知道为什么要将消息发送到死信以调试此类错误?

1 个答案:

答案 0 :(得分:1)

这是一个疯狂的猜测,但我很确定你的消息正在杀死你的演员(Exception被抛出)。如果您没有任何特殊SupervisorStrategy,则默认情况下将重新创建您的actor的新实例。那么有必要认为如果你不等待发送两条消息,第二条消息就不会到达你的演员,因为新的实例正在创建。但是,如果稍等一下,将创建新实例并准备好接收消息。

要测试是否是这种情况,您可以在演员死亡时将SupervisorStrategy更改为日志,也可以在try-catch定义上放置receive阻止。