08
Sep

Akka Actor Lifecycle Explained

akka-banner

Do you know what happens when you create an Akka actor and when it stops? So, the lifecycle of an actor starts automatically after its instantiation.

Actors are known as a unit of execution in the Akka. The Actor model is an abstraction that allows us to write correct concurrent, parallel, and distributed systems. Its prime role is to recognise the received message type and act accordingly.

Actor Lifecycle

The lifecycle of an actor starts when the actorOf() method is called (either by the system or the context). It provides various methods for Actors, which we can override and implement accordingly.

Actor lifecycle methods

preStart()
You can override the preStart() method to provide the implementation for an Actor. We can allocate resources before an actor starts, like database connections, files, etc.

import akka.actor. {
Actor,
ActorSystem,
Props
}
object Application extends App {
val system = ActorSystem("UserProfileActorSystem ")
val actor = system.actorOf(Props[UserProfile], "actor")
actor!"Please update user details."
}
class UserProfile extends Actor {
override def receive: Receive = {
case message => println(message)
}
override def preStart(): Unit = {
println("preStart() method called...")
}
}

postStop()

We can override the postStart() method to provide a specific implementation for an Actor. Once a method is called, the actor will stop receiving new messages, and the current messages will be redirected to the dead letter mailbox. This method is called after the actors stop to release resources.

import akka.actor. {
Actor,
ActorSystem,
Props
}
class UserProfile extends Actor {
override def receive: Receive = {
case message => println(message)
}
override def postStop(): Unit = {
println("postStop() method called...")
}
}
object Application extends App {
val system = ActorSystem("UserProfileActorSystem")
val actor = system.actorOf(Props[UserProfile], "actor")
actor!"User Details updated."
system.stop(actor)
}

preRestart()

We can override the preRestart() method to provide a specific implementation. This method calls when the actor is about to restart due to some exception. This method helps to handle in case an actor fails due to some exception.

import akka.actor. {
Actor,
ActorSystem,
Props
}
class UserProfile extends Actor {
override def receive: Receive = {
case number: Int => number / 0
case message => println(message)
}
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
println("preRestart() method called...") println("Reason : " + reason)
}
}
object Application extends App {
val system = ActorSystem("UserProfileActorSystem") val actor = system.actorOf(Props[UserProfile], "actor") actor!20
}

postRestart():

We can override the postRestart() method to provide a specific implementation for an Actor when the actor has restarted due to some exception. It allows an actor to reinitialise after an Actor fails or stops working due to an exception. Let’s take an example:

package org.bootstrap
import akka.actor. {
Actor,
ActorSystem,
Props
}
class UserProfile extends Actor {
override def receive: Receive = {
case number: Int => number / 0
case message => println(message)
}
override def postRestart(reason: Throwable): Unit = {
println("postRestart() method called...") println("Reason: " + reason)
}
}
object Application extends App {
val system = ActorSystem("UserProfileActorSystem") val actor = system.actorOf(Props[UserProfile], "actor") actor!20
}
Below is the example combining all the life cycle functions: import akka.actor. {
Actor,
ActorSystem,
Props
}
class UserProfile extends Actor {
override def receive: Receive = {
case message: String => println(message) case number: Int => number / 0
}
override def preStart(): Unit = {
println("preStart() method called...")
}
override def postStop(): Unit = {
println("postStop() method called...")
}
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
println("preRestart() method called...") println("Reason: " + reason)
}
override def postRestart(reason: Throwable): Unit = {
println("postRestart() method called...") println("Reason: " + reason)
}
}
object Application extends App {
  val system = ActorSystem("UserProfileActorSystem")
 
  val actor = system.actorOf(Props[UserProfile], "actor")
 
  // Scenario 1: Sending a message
  actor ! "Please update user details."
 
  // Stop the actor
  system.stop(actor)
 
  // Scenario 2: Sending a message again
  val actorTwo = system.actorOf(Props[UserProfile], "actorTwo")
  actorTwo ! "User Details updated."
 
  // Scenario 3: Causing a divide-by-zero error with a different message
  val actor3 = system.actorOf(Props[UserProfile], "actorThree")
  actorThree ! 20
}

When you run this code, it will execute the scenarios sequentially and produce the following output:

preStart() method called...
Please update user details.
postStop() method called...
preStart() method called...
User Details updated.
preRestart() method called...
Reason: java.lang.ArithmeticException: / by zero
postRestart() method called...
Reason: java.lang.ArithmeticException: / by zero
preStart() method called...

Conclusion

In conclusion, the Akka Actor Lifecycle is a fundamental aspect of building concurrent and distributed systems using the Actor model provided by Akka. Actors serve as the execution units in Akka, and their lifecycle consists of several key methods like the Akka toolkit that can be overridden and customised.

Understanding and utilising these methods is crucial for creating resilient and fault-tolerant systems. By customising these lifecycle hooks, developers can control how actors initialise, handle exceptions, and clean up resources. The Actor model, coupled with these lifecycle methods, simplifies the development of concurrent systems and aids in building robust applications capable of handling failures effectively.

About Ficode:

As the best Software Company in the UK, Ficode has been helping small and medium businesses adapt to the latest technologies and custom software solutions for over a decade. We bring years of experience, technology expertise, and quality skills to the table. Connect with us to know how we can transform your business with software.

share

Highcharts Implementation in Angular

Highcharts Implementation in Angular

previous-blog-arrowPrevious
Cross-browser Testing

Cross-browser Testing

next-blog-arrowNext

Memberships / Affiliations