0
votes

I have the following scenario: the parent supervisor actor creates a child for each message using a factory (function) passed in the constructor.

class supervisorActor(childActorMaker: ActorRefFactory => ActorRef)
  extends Actor with ActorLogging{

  def receive: Receive = {

    case "testThis" =>
      val childActor = childActorMaker(context)
      childActor!"messageForChild"
  }

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

class childActor extends Actor  {
   def receive:Receive = {
      case _ => /** whatever **/
   }
}

In the test I override the child Receive to force an exception. My expectation is the child actor to be stopped every time because of the Supervision Strategy i set.

"When the child Actor throws an exception the Supervisor Actor " should " " +
    " stop it" in {

    val childActorRef = TestActorRef(new childActor() {
      override def receive = {
        case msg: String => throw new IllegalArgumentException("kaboom")
      }
    })
    watch(childActorRef)

    val maker = (_: ActorRefFactory) => childActorRef
    val supervisorActorRef = system.actorOf(Props(new supervisorActor(maker)))

    supervisorActorRef!"testThis"

    expectTerminated(childActorRef, 1.second)
}

I would expect the child actor to be stoped because of the supervisorStrategy Stop. Instead I get this error:

java.lang.AssertionError: assertion failed: timeout (1 second) during expectMsg: Terminated

Any idea of why is this happening? Thank you

1

1 Answers

3
votes

It seems that the childActorRef is not created with supervisorActorRef's context (I mean ActorContext of supervisorActor you created in the test code). So childActor(childActorRef) is not a child of supervisorActor(supervisorActorRef) in your test code. That's why supervisor strategy of supervisorActor doesn't serve the purpose.