Table of contents
1.
Introduction 📃
2.
Integration with Akka 🧩
2.1.
Application Actor System 📌
2.1.1.
Writing Actors📝
2.1.2.
Creating and Using Actors 🚀
2.1.3.
Asking Things of Actors 📋
2.2.
Dependency Injecting Actors📌
2.3.
Configuration 📻
2.3.1.
Changing Configuration Prefix 📇
2.3.2.
Built-in Actor System Name 💹
2.4.
Using Your Actor System📌
2.5.
Akka Coordinated Shutdown📌
2.6.
Akka Cluster 📌
3.
Frequently Asked Questions 
3.1.
What is Scala?
3.2.
Why is it important to declare the controller to be a singleton?
3.3.
Is it possible to create your actor system in Play?
3.4.
What is Akka?
3.5.
What exactly does a Scala developer do?
4.
Conclusion 
Last Updated: Mar 27, 2024
Medium

Scala developers - Integration with Akka

Author Teesha Goyal
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction 📃

Scala is an open-source, general purpose, multiple paradigm programming language. It supports both functional and object-oriented programming principles. One of the most used web frameworks of Scala is Play. 

To learn more about Scala, visit What is Scala?

Introduction

In this article, we will discuss Integration with Akka for Scala Developers. 

Integration with Akka 🧩

Akka is an open-source library and toolset employed to develop distributed, concurrent, scalable, and fault-tolerant applications. It is compatible with any JVM-supported language. It employs the Actor Model, which provides a greater degree of abstraction. 

For fault-tolerance, Akka uses the 'Let it crash' model, which makes it a great success when dealing with self-heal systems.

Integration with Akka

Application Actor System 📌

The actor systems are the containers for actors in Akka. It is responsible for managing the resources to run the actors within it.  

Application Actor System

 

Play, a Scala-based web framework, defines a particular actor system that our application will use. This actor system tracks the application's life cycle, so it restarts automatically when the application restarts.

Writing Actors📝

Let's now discuss how to write actors. You will be required to write actors to use Akka. Following is a simple example of how you can define actors in Akka:

import akka.actor._
 
object HelloNinjaActor {
  def props = Props[HelloNinjaActor]
 
  case class SayHello(name: String)
}
 
class HelloNinjaActor extends Actor {
  import HelloActor._
 
  def receive = {
   case SayHello(name: String) =>
    sender() ! "Hello! Ninja - " + name
  }
}


Input

Syna

Output

Hello! Ninja - Syna

In the above example, the defined actor says Hello! Ninja - <name>. You can pass on the name, and the <name> is replaced by the actual name. 

Creating and Using Actors 🚀

Now that you have written and created an actor, you can use it with the help of ActorSystem, which is a container for actors. It is done by declaring a dependency on an ActorSystem as shown below:

import play.api.mvc._
import akka.actor._
import javax.inject._
 
import actors.HelloNinjaActor
 
@Singleton
class Application @Inject() (system: ActorSystem, cc: ControllerComponents) extends AbstractController(cc) {
  val helloActor = system.actorOf(HelloNinjaActor.props, "hello-actor")
 
  //...
}

Output 

*New actor is created*
Hello! Ninja - hello-actor

The actorOf method is used in the above example to create a new actor.

Note: You have to declare the controller to be a singleton; otherwise, a new actor object will be created each time a new controller is created. It will be a problem as you cannot have more than one actor in the same system with the same name. It will throw an error. Hence it is good practice to declare the controller to be a singleton.

Asking Things of Actors 📋

Sending a message to an actor is the most fundamental thing you can do. It works on a principle usually referred to as the tell pattern. There is no reaction when you send a message to an actor; it's fire and forget principle.

But when you are working with web applications, this tell pattern will not work as web applications use HTTP protocols that work with requests and responses. Here, you will need the ask pattern. The ask pattern returns Future data, which you can convert to any return type you wish. 

 Asking Things of Actors

Following is an example to illustrate the use of the ask pattern discussed above with the same HelloNinjaActor example:

 

import akka.pattern.ask
import scala.concurrent.duration._
implicit val timeout: Timeout = 5.seconds
 
def sayHello(name: String) = Action.async {
  (helloNinjaActor ? SayHello(name)).mapTo[String].map { message =>
   Ok(message)
  }
}

 

🛑 Note: 
 

📑 You need to import ask explicitly using import akka.pattern.ask. 
 

📑 After importing the ask pattern, you can use the question mark (?) operator on the actor.
 

📑 Since the return type of ask is Future[Any], you will have to convert the return type to your desired return type using the mapTo method.
 

📑 You also need to define an implicit timeout in scope. If the Actor takes more than that amount of time to react, it will be handled with a timeout error.

Dependency Injecting Actors📌

Dependency injections are used to bound several handlers with the specific instances of the application to provide customizability. By using dependency injection, you can have Guice create instances of actors and bind actor ref to them. The actor ref is the one on which the controllers and components depend. 

 Dependency Injecting Actors

Following is an example of how you can achieve this: 

import javax.inject._
import akka.actor._
import play.api.Configuration
 
object ConfiguredActor {
  case object GetConfig
}
 
class ConfiguredActor @Inject() (configuration: Configuration) extends Actor {
  import ConfiguredActor._
 
  val config = configuration.getOptional[String]("my.config").getOrElse("none")
 
  def receive = {
   case GetConfig =>
    sender() ! config
  }
}

Actor bindings become more straightforward when using Play as Play provides various helpers to make things easier. These helpers allow the Actor to be dependency injected and the actor ref to be injected into other application components.

Create a module as indicated in the dependency injection documentation, then mix in the AkkaGuiceSupport interface and bind the Actor using the bindActor method.

import play.api.libs.concurrent.AkkaGuiceSupport
import com.google.inject.AbstractModule
 
import actors.ConfiguredActor
 
class MyHelperModule extends AbstractModule with AkkaGuiceSupport {
  override def configure = {
   bindActor[ConfiguredActor]("configured-actor")
  }
}

Now that you have bound the actor ref to the instantiated actor, you can depend on your actor in the controllers and other components as shown below:

import play.api.mvc._
import akka.pattern.ask
import akka.actor._
import javax.inject._
import akka.util.Timeout
import scala.concurrent.ExecutionContext
import actors.ConfiguredActor._
import scala.concurrent.duration._
 
@Singleton
class Application @Inject() (@Named("configured-actor") configuredActor: ActorRef, components: ControllerComponents)(
   implicit ec: ExecutionContext
) extends AbstractController(components) {
  implicit val timeout: Timeout = 5.seconds
 
  def getConfig = Action.async {
   (configuredActor ? GetConfig).mapTo[String].map { message =>
    Ok(message)
   }
  }
}

Configuration 📻

Play already has a default actor system configuration which can be read from the Play application configuration file. Following is an example of how you can configure the default dispatcher of the application actor system by adding just a few lines to the conf/application.conf file: 
 

akka.actor.default-dispatcher.fork-join-executor.parallelism-max = 64
akka.actor.debug.receive = on

To learn more about logging configuration, visit Configuration Logging

Changing Configuration Prefix 📇

If you are using the akka.* for some Akka actor system and want to load the Akka settings for another actor system, you have the option to instruct Play to load it from another location as shown below:
 

play.akka.config = "my-akka"

 

Now by using the above command, you changed the configuration prefix. The Akka settings will be loaded from the my-akka prefix and not the akka prefix
 

my-akka.actor.default-dispatcher.fork-join-executor.parallelism-max = 64
my-akka.actor.debug.receive = on

Built-in Actor System Name 💹

The application is the default name for an actor system in the Play software. However, you have the option to change the name by writing the below line in your conf/application.conf file:
 

play.akka.actor-system = "Your-Actor-System-Name"

Using Your Actor System📌

Although it is recommended to use the built-in actor system as it minimizes your efforts by providing the correct classloader, lifecycle hooks, etc. You can still create your actor system whenever you want.  

To build your actor system, make sure you do the following:
 

📋 You must set up a stop hook so that the actor system shuts down when the Play shuts down.
 

📋 Ensure that you pass in the right classloader from the Play Environment, or else Akka won't be able to locate your application's classes.
 

📋 Ensure that you either use play.akka.config to modify the position from which Play receives its Akka configuration or that you do not read your Akka configuration from the default akka config, since this can create difficulties when the system tries to bind to the same remote ports.

Akka Coordinated Shutdown📌

A shutdown is an important factor when dealing with applications. Fortunately, Play provides a simple way to shut down your application and server. It is done using Akka's Coordinated Shutdown. 

Akka Coordinated Shutdown

To learn more about this, visit Coordinated Shutdown

Note: Play is exclusively in charge of shutting down its internal ActorSystem. If you're employing different actor systems, ensure they're all terminated, and feel free to migrate to Coordinated Shutdown.

Akka Cluster 📌

Akka Cluster offers a fault-tolerant distributed peer-to-peer Cluster Membership Service with no single failure point or bottleneck. You may join an existing Akka Cluster with your Play application. In that situation, it is advised that you properly exit the cluster. Play ships with Akka's Coordinated Shutdown, which will handle the graceful exit.

Akka Cluster 

It is advised that you replace any custom Cluster Leave code with Akka's handling.

Frequently Asked Questions 

What is Scala?

Scala is an open-source, general purpose, multiple paradigm programming language. It supports both functional and object-oriented programming principles.

Why is it important to declare the controller to be a singleton?

You have to declare the controller to be a singleton. Otherwise, a new actor will be created each time a new controller is created. It will cause a problem as you cannot have more than one actor in the same system with the same name. It will throw an error.

Is it possible to create your actor system in Play?

Although it is recommended to use the built-in actor system as it minimizes your efforts by providing the correct classloader, lifecycle hooks, etc. You can still create your actor system whenever you want.  

What is Akka?

Akka is an open-source library and toolset employed to develop distributed, concurrent, scalable, and fault-tolerant applications. It is compatible with any JVM-supported language. It employs the Actor Model, which provides a greater degree of abstraction. 

What exactly does a Scala developer do?

A Scala developer is responsible for designing, developing, and managing scala-based web applications. They should be familiar with the concepts, including but not limited to functional and object-oriented programming paradigms.  

Conclusion 

This article discussed Integration with Akka for Scala developers. We have discussed in detail how to integrate your application with Akka.

To read interview questions related to Scala, visit Scala Interview Questions - Coding Ninjas Coding Ninjas Studio

I hope you would have gained a better understanding of these topics now!

Are you planning to ace the interviews with reputed product-based companies like AmazonGoogleMicrosoft, and more? 

Attempt our Online Mock Test Series on Coding Ninjas Studio now!

Happy Coding!

Live masterclass