user79074
user79074

Reputation: 5270

How to stop an Actor reloading on exception

In a scenario where an exception is thrown in an Actor receive I want to prevent this actor from being reloaded. I understood that the correct way to do this is by overriding supervisorStrategy but this does not work as shown in the example below:

class MyActor extends Actor {

    println("Created new actor")

    def receive = {
        case msg =>
            println("Received message: " + msg)
            throw new Exception()
    }

    override val supervisorStrategy = OneForOneStrategy() {
        case _: Exception => Stop
    }
}

val system = ActorSystem("Test")
val actor = system.actorOf(Props(new MyActor()))
actor ! "Hello"

When I run this code "Created new actor" is output twice showing that the Actor is reloaded again after the exception.

What is the correct way to prevent the Actor being reloaded?

Upvotes: 1

Views: 71

Answers (1)

Jeffrey Chung
Jeffrey Chung

Reputation: 19497

When an actor overrides the default supervisor strategy, that strategy applies to that actor's children. Your actor is using the default supervisor strategy, which restarts actors when they throw an exception. Define a parent for your actor and override the supervisor strategy in that parent.

class MyParent extends Actor {
  override val supervisorStrategy = OneForOneStrategy() {
    case _: Exception => Stop
  }

  val child = context.actorOf(Props[MyActor])

  def receive = {
    case msg =>
      println(s"Parent received the following message and is sending it to the child: $msg")
      child ! msg
  }
}

class MyActor extends Actor {
  println("Created new actor")

  def receive = {
    case msg =>
      println(s"Received message: $msg")
      throw new Exception()
  }
}

val system = ActorSystem("Test")
val actor = system.actorOf(Props[MyParent])
actor ! "Hello"

In the above example, a MyActor is created as a child of MyParent. When the latter receives the "Hello" message, it sends the same message to the child. The child is stopped when it throws the exception, and "Created new actor" is therefore printed only once.

Upvotes: 5

Related Questions