Reputation: 691
Im pretty new to Akka and I'm having some issues when trying to do integration tests with my actors.
I have a 'TalkerSocket' actor with this receive:
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")
}
And I'm testing like this:
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)
}
When I do:
platoSocket ! authMessage(platoId)
Everything looks ok.
When I try to send two messages, for example:
platoSocket ! authMessage(platoId)
platoSocket ! authMessage(platoId)
I got an error with the second one:
[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'.
For curiosity I try:
platoSocket ! authMessage(platoId)
Thread.sleep(1000)
platoSocket ! authMessage(platoId)
And I don't get any error message from Dead Letter.
Anybody knows what's happening here? Is there a way to know WHY a message is sent to a Dead Letter in order to debug this kind of errors?
Upvotes: 1
Views: 529
Reputation: 6915
This is a wild guess but I am pretty sure your message is killing your actor (an Exception
is getting thrown). If you don't have any special SupervisorStrategy
then a new instance of your actor will get recreated by default. Then it makes sense to think that if you send two messages without waiting, the second one will not reach your actor since the new instance is getting created. However, if you wait a bit, the new instance will be created and ready to receive messages.
To test if that is the case you can either change your SupervisorStrategy
to log when the actor is dying or you can place a try-catch
block on your receive
definition.
Upvotes: 2