CODESAMPLE
Master-Slave - Scala
The Master-Slave pattern distributes work to worker nodes (slaves) from a central coordinator (master). The master assigns tasks, and slaves execute them independently, returning results to the master. This example uses Scala Actors to implement the pattern. The Master actor receives tasks and distributes them to available Worker actors. Each Worker processes a task and sends the result back to the master. Scala Actors provide a natural concurrency model for this, handling message passing and worker lifecycle. This implementation is idiomatic Scala due to its use of Actors for concurrent processing and immutable data for task representation.
import akka.actor._
import scala.util.Random
object MasterSlave {
case class Task(id: Int, data: Int)
case class Result(taskId: Int, value: Int)
class Master extends Actor {
var workers: Vector[ActorRef] = Vector.empty
var results: Vector[Result] = Vector.empty
def receive: Receive = {
case worker: ActorRef =>
workers = workers :+ worker
println(s"Master: Worker joined - ${worker.path}")
case task: Task =>
println(s"Master: Received task ${task.id}")
if (workers.nonEmpty) {
val worker = workers(Random.nextInt(workers.length))
worker ! task
} else {
println("Master: No workers available.")
}
case result: Result =>
results = results :+ result
println(s"Master: Received result for task ${result.taskId} - ${result.value}")
if (results.length == 5) { // Example: Wait for 5 results
println("Master: All tasks completed.")
context.stop(self)
}
}
}
class Worker extends Actor {
def receive: Receive = {
case task: Task =>
println(s"Worker: Processing task ${task.id}")
val result = task.data * 2 // Simulate some work
sender() ! Result(task.id, result)
println(s"Worker: Finished task ${task.id}")
}
}
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("MasterSlaveSystem")
val master = system.actorOf(Props[Master], "master")
// Create and register workers
for (i <- 1 to 3) {
val worker = system.actorOf(Props[Worker], s"worker-$i")
master ! worker
}
// Send tasks
for (i <- 1 to 5) {
master ! Task(i, i * 10)
}
}
}