|
Akka/Scala example source code file (DiningHakkersOnBecome.scala)
The DiningHakkersOnBecome.scala Akka example source codepackage sample.become import akka.actor._ import scala.concurrent.duration._ // Akka adaptation of // http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/ /* * First we define our messages, they basically speak for themselves */ sealed trait DiningHakkerMessage final case class Busy(chopstick: ActorRef) extends DiningHakkerMessage final case class Put(hakker: ActorRef) extends DiningHakkerMessage final case class Take(hakker: ActorRef) extends DiningHakkerMessage final case class Taken(chopstick: ActorRef) extends DiningHakkerMessage object Eat extends DiningHakkerMessage object Think extends DiningHakkerMessage /* * A Chopstick is an actor, it can be taken, and put back */ class Chopstick extends Actor { import context._ //When a Chopstick is taken by a hakker //It will refuse to be taken by other hakkers //But the owning hakker can put it back def takenBy(hakker: ActorRef): Receive = { case Take(otherHakker) => otherHakker ! Busy(self) case Put(`hakker`) => become(available) } //When a Chopstick is available, it can be taken by a hakker def available: Receive = { case Take(hakker) => become(takenBy(hakker)) hakker ! Taken(self) } //A Chopstick begins its existence as available def receive = available } /* * A hakker is an awesome dude or dudett who either thinks about hacking or has to eat ;-) */ class Hakker(name: String, left: ActorRef, right: ActorRef) extends Actor { import context._ //When a hakker is thinking it can become hungry //and try to pick up its chopsticks and eat def thinking: Receive = { case Eat => become(hungry) left ! Take(self) right ! Take(self) } //When a hakker is hungry it tries to pick up its chopsticks and eat //When it picks one up, it goes into wait for the other //If the hakkers first attempt at grabbing a chopstick fails, //it starts to wait for the response of the other grab def hungry: Receive = { case Taken(`left`) => become(waiting_for(right, left)) case Taken(`right`) => become(waiting_for(left, right)) case Busy(chopstick) => become(denied_a_chopstick) } //When a hakker is waiting for the last chopstick it can either obtain it //and start eating, or the other chopstick was busy, and the hakker goes //back to think about how he should obtain his chopsticks :-) def waiting_for(chopstickToWaitFor: ActorRef, otherChopstick: ActorRef): Receive = { case Taken(`chopstickToWaitFor`) => println("%s has picked up %s and %s and starts to eat".format(name, left.path.name, right.path.name)) become(eating) system.scheduler.scheduleOnce(5.seconds, self, Think) case Busy(chopstick) => otherChopstick ! Put(self) startThinking(10.milliseconds) } //When the results of the other grab comes back, //he needs to put it back if he got the other one. //Then go back and think and try to grab the chopsticks again def denied_a_chopstick: Receive = { case Taken(chopstick) => chopstick ! Put(self) startThinking(10.milliseconds) case Busy(chopstick) => startThinking(10.milliseconds) } //When a hakker is eating, he can decide to start to think, //then he puts down his chopsticks and starts to think def eating: Receive = { case Think => left ! Put(self) right ! Put(self) println("%s puts down his chopsticks and starts to think".format(name)) startThinking(5.seconds) } //All hakkers start in a non-eating state def receive = { case Think => println("%s starts to think".format(name)) startThinking(5.seconds) } private def startThinking(duration: FiniteDuration): Unit = { become(thinking) system.scheduler.scheduleOnce(duration, self, Eat) } } /* * Alright, here's our test-harness */ object DiningHakkersOnBecome { val system = ActorSystem() def main(args: Array[String]): Unit = run() def run(): Unit = { //Create 5 chopsticks val chopsticks = for (i <- 1 to 5) yield system.actorOf(Props[Chopstick], "Chopstick" + i) //Create 5 awesome hakkers and assign them their left and right chopstick val hakkers = for { (name, i) <- List("Ghosh", "Boner", "Klang", "Krasser", "Manie").zipWithIndex } yield system.actorOf(Props(classOf[Hakker], name, chopsticks(i), chopsticks((i + 1) % 5))) //Signal all hakkers that they should start thinking, and watch the show hakkers.foreach(_ ! Think) } } Other Akka source code examplesHere is a short list of links related to this Akka DiningHakkersOnBecome.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.