Scala Lesson 54 – Actors Project | Dataplexa

Actors Project in Scala

In this lesson, you will build a real-world Actors-based project using Scala. This project will help you understand how actors work in practice and how they are used to build scalable, concurrent systems.

We will design a simple Task Processing System where actors communicate with each other by sending messages.


What Are Actors?

Actors are a concurrency model where independent entities (actors) communicate only by sending messages.

Each actor:

  • Has its own state
  • Processes one message at a time
  • Does not share mutable memory
  • Communicates asynchronously

This model makes concurrent systems easier to reason about and safer to scale.


Project Overview

We will build a Task Manager system consisting of:

  • A Manager Actor that assigns tasks
  • Multiple Worker Actors that process tasks
  • Message-based communication between actors

This pattern is commonly used in:

  • Job scheduling systems
  • Background task processing
  • Distributed services

Defining Messages

Actors communicate using messages, usually defined as case classes.

// Messages
case class Task(id: Int, description: String)
case object Start
case object Stop

These messages will be exchanged between the manager and workers.


Creating a Worker Actor

The worker actor processes tasks sent by the manager.

import akka.actor.Actor

class Worker extends Actor {

  def receive: Receive = {
    case Task(id, description) =>
      println(s"Worker ${self.path.name} processing task $id: $description")
  }
}

Each worker processes one task at a time and prints the result.


Creating a Manager Actor

The manager creates workers and distributes tasks among them.

import akka.actor.{Actor, ActorRef, Props}

class Manager extends Actor {

  val workers: Seq[ActorRef] =
    for (i <- 1 to 3)
      yield context.actorOf(Props[Worker], s"worker-$i")

  def receive: Receive = {
    case Start =>
      workers.zipWithIndex.foreach {
        case (worker, index) =>
          worker ! Task(index + 1, s"Task assigned to ${worker.path.name}")
      }

    case Stop =>
      context.system.terminate()
  }
}

The manager creates three workers and assigns tasks when it receives Start.


Starting the Actor System

Now we create the actor system and start the project.

import akka.actor.ActorSystem

object ActorProject extends App {

  val system = ActorSystem("TaskSystem")

  val manager = system.actorOf(Props[Manager], "manager")

  manager ! Start
}

Running this program will distribute tasks to worker actors.


How the Project Works

The execution flow is:

  1. Actor system starts
  2. Manager actor is created
  3. Workers are initialized
  4. Tasks are sent as messages
  5. Workers process tasks independently

All communication happens asynchronously.


Why Actors Are Powerful

This project demonstrates several benefits of the actor model:

  • No shared mutable state
  • Safe concurrency
  • Scalability by adding more workers
  • Fault isolation

Extending the Project

You can extend this project by:

  • Adding task completion acknowledgments
  • Handling failures and retries
  • Persisting task results
  • Distributing actors across machines

📝 Practice Exercises


Exercise 1

Modify the worker to simulate task processing using a delay.

Exercise 2

Increase the number of workers dynamically.

Exercise 3

Add a message to shut down the system gracefully.


✅ Practice Answers


Answer (Example Delay)

case Task(id, description) =>
  Thread.sleep(500)
  println(s"Completed task $id")

What’s Next?

In the next lesson, you will learn about Data Processing in Scala, where you will handle and transform large datasets efficiently.