So I understand that if you send a message to a dead actor the message goes to DeadLetters but what happens to the messages that were already enqueued for that actor. Do they also get forwarded there or do they get lost?
In general, you can't assume much about delivery to dead letters. As the docs on dead letters say:
Messages which cannot be delivered (and for which this can be ascertained) will be delivered to a synthetic actor called
/deadLetters
. This delivery happens on a best-effort basis; it may fail even within the local JVM (e.g. during actor termination). Messages sent via unreliable network transports will be lost without turning up as dead letters.
However, it looks like Akka does make an effort to forward to dead letters messages that were already enqueued for the actor. This is a snippet from the cleanup
function for Mailbox
, which gets called after the actor has been shutdown:
/**
* Overridable callback to clean up the mailbox,
* called when an actor is unregistered.
* By default it dequeues all system messages + messages and ships them to the owning actors' systems' DeadLetterMailbox
*/
protected[dispatch] def cleanUp(): Unit =
if (actor ne null) { // actor is null for the deadLetterMailbox
val dlm = actor.dispatcher.mailboxes.deadLetterMailbox
var messageList = systemDrain(new LatestFirstSystemMessageList(NoMessage))
while (messageList.nonEmpty) {
// message must be “virgin” before being able to systemEnqueue again
val msg = messageList.head
messageList = messageList.tail
msg.unlink()
dlm.systemEnqueue(actor.self, msg)
}
if (messageQueue ne null) // needed for CallingThreadDispatcher, which never calls Mailbox.run()
messageQueue.cleanUp(actor.self, actor.dispatcher.mailboxes.deadLetterMailbox.messageQueue)
}
}