Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

With Akka

Integrating Akka actors in a Play Framework application allows you to take advantage of the actor model for handling concurrency, scalability, and fault tolerance. Actors are ideal for scenarios where you need to manage state in an asynchronous, non-blocking manner or when you need to perform long-running or compute-intensive tasks in response to HTTP requests. Here's a basic guide on how to use Akka actors within a Play Framework application:

Step 1: Define an Actor

First, define your actor class. Actors handle messages and can maintain state. Create a Scala class file in the app/actors directory of your Play project (you might need to create the directory first). Here's an example of a simple actor that echoes messages back:

package actors

import akka.actor.Actor

class EchoActor extends Actor {
  def receive = {
    case message: String => sender() ! message // Echoes the message back to the sender
  }
}

Step 2: Configure Actor System

Play Framework automatically provides an ActorSystem for you. You can access this system and use it to create actor instances. The ActorSystem is a heavyweight structure that controls the lifecycle of your actors and is capable of managing hundreds or thousands of actors.

Step 3: Create and Use an Actor in a Controller

Next, create a controller that sends a message to your actor and waits for a response. This example demonstrates how to do this asynchronously using ask pattern from Akka. You'll need to modify your controller to inject the ActorSystem and use it to create actor instances.

Add the following imports to your controller file:

import akka.actor.ActorSystem
import akka.util.Timeout
import actors.EchoActor
import akka.pattern.ask
import scala.concurrent.duration._
import scala.concurrent.Future
import play.api.mvc._
import javax.inject._

Then, define your controller and action method:

@Singleton
class EchoController @Inject()(val controllerComponents: ControllerComponents, actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends BaseController {

  implicit val timeout: Timeout = 5.seconds

  def echo(message: String) = Action.async {
    val echoActor = actorSystem.actorOf(Props[EchoActor], "echo-actor")
    val futureResponse: Future[String] = (echoActor ? message).mapTo[String]
    futureResponse.map { response =>
      Ok(response)
    }
  }
}

In this controller:

  • An EchoActor instance is created using the ActorSystem.
  • The echo action method sends a message to the EchoActor using the ask pattern and waits for a response.
  • The response from the actor is sent back to the client as an HTTP response.

Step 4: Add Routes

Define a route for your action in the conf/routes file:

GET     /echo/:message        controllers.EchoController.echo(message)

Step 5: Test Your Actor

Run your Play application, and access the route /echo/Hello in your browser or via a tool like curl. You should receive the echoed message in response.

Note

Using actors for simple echo tasks might be overkill. The real power of actors comes into play when managing complex states, performing long-running tasks, or handling a high number of concurrent operations. Remember, actors are just one of many tools offered by Play and Akka for building reactive applications, and they're best used when their specific capabilities align with your application's requirements.