我是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的任何错误消息。
有人知道这里发生了什么吗?有没有办法知道为什么要将消息发送到死信以调试此类错误?
答案 0 :(得分:1)
这是一个疯狂的猜测,但我很确定你的消息正在杀死你的演员(Exception
被抛出)。如果您没有任何特殊SupervisorStrategy
,则默认情况下将重新创建您的actor的新实例。那么有必要认为如果你不等待发送两条消息,第二条消息就不会到达你的演员,因为新的实例正在创建。但是,如果稍等一下,将创建新实例并准备好接收消息。
要测试是否是这种情况,您可以在演员死亡时将SupervisorStrategy
更改为日志,也可以在try-catch
定义上放置receive
阻止。