Maximus
Maximus

Reputation: 559

Akka Stop/Kill actors after processing completion

I would like to know how to efficiently cleanup akka actors that are created on the fly.

To give a bit of background:

Actor Hierarchy created per event.

Supervisor -> child1 -> grandChild1

In my application the supervisor actor dynamically creates other actors(on a periodic event). I wanted to cleanup the actors after the processing steps for that event is complete.

So, I would like to kill all the child actors once the processing is complete.

  1. I am propagating a message (successfulProcessing) after successful completion in the reverse of creation. (Grandchild1 -> child1 -> Supervisor ). In the Supervisor, I will send a PoisonPill to the child actor.

This is the code for the Supervisor actor.

class Supervisor extends Actor {
    def receive={
        case onEvent: OnEvent =>
            //Create child actor and send message         
        case successfulProcessing =>
            sender() ! PoisonPill
    }
    override val supervisorStrategy = AllForOneStrategy() {
        case e: Exception =>
            Stop   
    }
}

Is this the correct approach to cleanup the dynamically created actors. If there is any disadvantage to this approach or is there a pattern to be followed?

Upvotes: 3

Views: 1756

Answers (2)

Advika
Advika

Reputation: 595

As per Akka Document 2.4.14 , Better way to handle PoisonPill/Kill message is to broadcast them.

    ActorRef ! Broadcast(PoisonPill)

Note: Do not broadcast messages when using BalancingPool

Upvotes: 1

erip
erip

Reputation: 16945

The pattern I've seen is to have an actor who manages other actors. In the following example from this tutorial, actor1 manages actor2, where actor2 does all the work. actor1 then cleans up.

case class StartCounting(n: Int, actor: ActorRef)
case class CountDown(n: Int)

class CountDownActor extends Actor {
  def receive = {
    case StartCounting(n, actor) =>
      println(n)
      actor ! CountDown(n-1)
    case CountDown(n) =>
      if(n > 0) {
        println(n)
        sender ! CountDown(n-1)
      } else {
        context.system.shutdown()
      }
  }
}

object Main extends App {
  val system = ActorSystem("HelloSystem")
  // default Actor constructor
  val actor1 = system.actorOf(Props[CountDownActor], name = "manager")
  val actor2 = system.actorOf(Props[CountDownActor], name = "worker")
  actor1 ! StartCounting(10, actor2)
}

You can think of this like recursion: base and inductive cases. You can apply this at depth for all sibling actors being managed their parent.

Upvotes: 0

Related Questions