Question

I have the following code:

class A extends Actor with ActorLogging {
  override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 2) { 
    case _ => log.info("An actor has been killed"); Restart 
  }

  val b = context.system.actorOf(Props[B], "b")

  def receive = {
    case _ => context.system.scheduler.schedule(5 seconds, 5 seconds, b, true)
  }
}

class B extends Actor with ActorLogging {
  def receive = { case true => self ! Kill }
}

After self ! Kill in an instance of actor A I don't see a message "An actor has been killed" and subsequent call to actor A generates "dead letters" message so there was no restart. Why is OneForOneStrategy not getting called?

It's strange in a way that I can just remove the whole OneForOneStrategy override and there are no changes in program behavior whatsoever.

Was it helpful?

Solution

val b = context.system.actorOf(Props[B], "b") should be changed to val b = context.actorOf(Props[B], "b") to make new actor a child, not a top-level actor.

OTHER TIPS

You're simultaneously restarting the actor "B" and then throwing an exception when you restart it. Remove the self ! true from your postRestart code. Otherwise, what do you expect to happen? You're sending it into an infinitely recursive restart loop.

Here's the order or the actions you're seeing to illustrate it:

  1. Create actor "A"
  2. Create actor "B"
  3. send true to A
  4. send true to B
  5. "B" throws exception at true message
  6. "A" restarts "B"
  7. after restart "B" sends itself true
  8. repeat step 5
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top