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:
- Actor system starts
- Manager actor is created
- Workers are initialized
- Tasks are sent as messages
- 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.