Akka Dead Letters Channel

Akka doesn’t guarantee the delivery of a message. What happens when a message cannot be delivered? In this article we will describe how the Dead Letters Channel works and how it can be used to spot issues in our system.

How it works

In a previous article we have described the use of Event Streams in Akka. The Dead Letter Channel is nothing more that a special Event Stream that the system uses internally every time a message cannot be delivered: either because the message cannot be processed or delivered.

When Akka is redirecting the failed message to the Dead Letter actor, it wraps the message in a case class called Dead Letter to provide the message, the original sender and recipient:

case class DeadLetter(message: Any, sender: ActorRef, recipient: ActorRef)

Unless specified differently, dead letters are logged in the INFO level: more information on how to tweak your logging settings can be found here.

How to use it

Because the Dead Letter Channel is an Event Stream, we can subscribe to it and listen to all the messages it publishes.

The code used for this tutorial is available here.

First of all, let’s create a dummy actor, called EchoActor, that prints all the messages it receives:

 
class EchoActor extends Actor {
  
  def receive = {
    case msg => println(s"New msg received: $msg")
  }
  
}

The second step is to create our actor system: we will have two instance of EchoActor, one called deadLettersSubscriber that will listen for DeadLetters and the other, called echoActor, that will simply wait and receive messages.

  implicit val system = ActorSystem("dead-letters-usage-example")

  val deadLettersSubscriber = system.actorOf(Props[EchoActor], name = "dead-letters-subscriber")
  val echoActor = system.actorOf(Props[EchoActor], name = "generic-echo-actor")

  system.eventStream.subscribe(deadLettersSubscriber, classOf[DeadLetter])

When successfully sending a message, no dead letter is generated.

  echoActor ! "First Message"
  // generic-echo-actor - New msg received: First Message

However, when we try to send a message to an actor that has been killed, the message is successfully transformed into a DeadLetter.

  echoActor ! PoisonPill
  echoActor ! "Second Message"
  // dead-letters-subscriber - New msg received: DeadLetter(Second Message,Actor[akka://dead-letters-usage-example/deadLetters],Actor[akka://dead-letters-usage-example/user/generic-echo-actor#317003256])
  // INFO  [RepointableActorRef]: Message [java.lang.String] from Actor[akka://dead-letters-usage-example/deadLetters] to Actor[akka://dead-letters-usage-example/user/generic-echo-actor#317003256] 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'.

Finally, we can also send messages directly to the Dead Letter Actor: this is usually not advised as the Dead Letter Channel should be reserved for the system to redirect failed messages.

  system.deadLetters ! "Dead Message"
  // dead-letters-subscriber - New msg received: DeadLetter(Dead Message,Actor[akka://dead-letters-usage-example/deadLetters],Actor[akka://dead-letters-usage-example/deadLetters])
  // INFO  [DeadLetterActorRef]: Message [java.lang.String] from Actor[akka://dead-letters-usage-example/deadLetters] to Actor[akka://dead-letters-usage-example/deadLetters] was not delivered. [2] 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'.

Summary

Akka redirects all the messages that couldn’t be delivered or process to the Dead Letter Channel. In this article we have discussed how Akka uses it and how we can exploit it when testing our system and investigating issues with our system.

Published by

Daniela Sfregola

Tech Leader at Paytouch

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s