Understanding Akka Actor Lifecycle

Reading Time: 3 minutes

So, here is a glimpse of how an Akka Actor Lifecycle works. The actor lifecycle begins as soon as the actor is created.

The stages of an Akka Actor Lifecycle are as follows –

  • preStart()
  • Start
  • Stop
  • postStop()
  • terminated

Starting Actors

val system = ActorSystem("name_of_system")
val actor = system.actorOf(Props[ActorClass])
  • Creating an actor automatically starts it.
  • A started actor is fully operable.
  • We can start an Actor with a preStart() hook.
  • And for more information, you could refer to: Creating the First Actor Guide.

Stopping Actor

context.stop(self)   //  to stop itself
System.stop(actorRef)  //  actor system will stop specified actor
context.stop(actorRef) // stop any other actor from current actor
actorRef ! PoisonPill //  get into the mailbox in the end
actorRef ! Kill  //  get into the mailbox in the end
  • An actor can stop itself and also it can stop another actor.
  • A stopped actor is no longer operable.
  • After the termination of the actor, we can override the postStop() hook, and now it would be available for garbage collection.

Stopping Actor with the API

  • Both ActorSystem and ActorContext provide a stop method.
  • Stopping an actor is an asynchronous and recursive operation:
    • The actor finishes processing the current message if any
    • Suspends message processing,
    • Stops its children, and
    • Waits for their termination confirmations and then terminates itself.
  • So, stopping an actor automatically stops all its descendants.

Stopping Actor with the PoisonPill and kill

  • PoisonPill and kill are specially handled messages that get enqueued into the actor’s mailbox and cause the actor to stop when they’re handled.
  • When an Actor handles a PoisonPill message it simply calls context.stop(self()).
  • When an actor handles a kill message it throws an ActorKilledException.
  • Both allow an actor to finish handling all messages placed in their mailbox before the PoisonPill or Kill.
  • Moreover, these behaviors can’t be overridden by handling the messages yourself, not appropriate when the Actor needs to perform cleanup before shutting down.

Elegant way to stop an actor

  • If an actor needs to perform certain tasks before stopping it
    • then it should advertise a dedicated message for that purpose,
    • handle it as appropriate and stop it after that and stop it after that.
  • And for more information you could refer to Akka Actors Stopping Guide.

Death Watch

context.watch(actorRef)
Termination(value)  // to keep a track that which actor died
  • An actor can monitor another actor’s termination, aka deathwatch
    • An actor could watch another actor and get notified of its termination.
    • Keep it in mind that an actor could not keep a watch on its own death.
  • On termination, the monitoring actor is sent a Terminated message
  • We have to handle Termination(value) to keep track that exactly which actor died? In case the actor is watching so many actors.
  • DeathPactException occurs when we do not handle a termination.
  • And for more information, you could also refer to DeadWatch API.

Actor Path

  • Within an actor system, actors are arranged in a hierarchy.
  • Therefore each actor has a parent.
  • Each actor has a name which is unique amongst its siblings.
  • The identification of an actor is through its unique sequence of names.
  • An ActorPath encapsulates a sequence of actor names with transport protocol and address of the actor system.
  • To obtain an actor path call path on ActorRef.
  • To get an actor’s name call name on ActorPath.
  • And for more information, you could also refer to Actor References, Paths, and Addresses Guide.

You can explore more about Akka Lifecycle here.