Search code examples
akkadead-letter

Where do enqueued messages go after an actor is stopped Akka


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?


Solution

  • 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)
        }
    }