Last active
May 14, 2017 10:35
-
-
Save miguelsaddress/0528fd6fb68e69d175b81a7c24bba358 to your computer and use it in GitHub Desktop.
Gist belonging to https://github.com/miguelsaddress/RebelAkktors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import akka.actor._ | |
import scala.concurrent.Await | |
import scala.concurrent.duration._ | |
object RebelAkktorsGist extends App { | |
/**************************** | |
* Messages * | |
***************************/ | |
case class Command(cmd: String) | |
case class FYou(cmd: Command) | |
case class Sudo(cmd: Command) | |
case class SendCommandTo(cmd: Command, to: ActorRef) | |
case class YesMeLord(response: String) | |
/**************************** | |
* Boss Actor * | |
***************************/ | |
object BossActor { | |
def props() = Props[BossActor] | |
} | |
class BossActor extends Actor { | |
val actorName = self.path.name | |
var waitingForActors = 0 | |
def receive = { | |
case SendCommandTo(cmd, actor) => | |
println(s"[$actorName] Sending command [$cmd] to [$actor]") | |
waitingForActors += 1 | |
actor ! cmd | |
case f @ FYou(c @ Command(cmd)) => { | |
println (s"[$actorName]: What, [${sender.path.name}]??? F* to me? F* To you!") | |
println(s"[$actorName]: Sending Sudo version... of [$c] to [${sender.path.name}]") | |
sender ! Sudo(c) | |
} | |
case YesMeLord(response) => { | |
waitingForActors -= 1 | |
println(s"[$actorName]: Good boy [${sender.path.name}]... I got your response [$response]") | |
if (waitingForActors == 0) { | |
println("Terminating...") | |
context.system.terminate() | |
} | |
} | |
} | |
} | |
/**************************** | |
* IT Guy Actor * | |
***************************/ | |
object ITGuyActor { | |
def props(rebelChances: Double) = Props[ITGuyActor](new ITGuyActor(rebelChances)) | |
} | |
class ITGuyActor(val rebelChances: Double) extends Actor { | |
assert(rebelChances > 0.0) | |
assert(rebelChances < 1.0) | |
val SUDO_ATTEMPTS_THRESHOLD = 3 | |
// we are assuming only one actor sends sudo | |
// messages... that is ok for our purposes | |
// his holds state as you can see ;) | |
var sudoAttempts = 0 | |
val actorName = self.path.name | |
override def preStart() = { | |
if (shouldGoRebel) { | |
println(s"[$actorName] Going wild...") | |
context.become(rebel) | |
} | |
} | |
def receive: Receive = { | |
case c @ Command(cmd) => | |
println(s"[$actorName]: received command [$c]...!") | |
println(s"[$actorName]: I am so obedient I will do it NOW...") | |
sender ! YesMeLord(s"[$actorName] I executed your command [$cmd], Me Lord") | |
case s @ Sudo(c @ Command(cmd)) => | |
println(s"[$actorName]: received Sudo command [$s]...!") | |
self ! c | |
} | |
def rebel: Receive = { | |
case c @ Command(cmd) => | |
println(s"[$actorName]: received command [$c]... but FYou System!") | |
sender ! FYou(c) | |
case s @ Sudo(c @ Command(cmd)) => | |
if (sudoAttempts < SUDO_ATTEMPTS_THRESHOLD) { | |
sudoAttempts += 1 | |
sender ! FYou(c) | |
} else { | |
sender ! YesMeLord(s"I executed your command [$cmd] after $sudoAttempts attempts. My family got the message, Me Lord") | |
sudoAttempts = 0 | |
context.stop(self) | |
} | |
} | |
private def shouldGoRebel: Boolean = { | |
val r = scala.util.Random | |
rebelChances > r.nextDouble | |
} | |
} | |
/******************************** | |
* Run the Sample * | |
*******************************/ | |
val system = ActorSystem("RebelAkktorsSystem") | |
val boss = system.actorOf(BossActor.props(), name = "TheBoss") | |
val obedientITGuy = system.actorOf(ITGuyActor.props(0.01), name = "ObedientItGuy") | |
val rebelITGuy = system.actorOf(ITGuyActor.props(0.95), name = "RebelItGuy") | |
println( "Here we go") | |
boss ! SendCommandTo(Command("Make me a Sandwich"), obedientITGuy) | |
boss ! SendCommandTo(Command("Make me a Sandwich"), rebelITGuy) | |
Await.ready(system.whenTerminated, 2 second) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here we go | |
[RebelItGuy] Going wild... | |
[TheBoss] Sending command [Command(Make me a Sandwich)] to [Actor[akka://RebelAkktorsSystem/user/ObedientItGuy#329592640]] | |
[TheBoss] Sending command [Command(Make me a Sandwich)] to [Actor[akka://RebelAkktorsSystem/user/RebelItGuy#-1940265609]] | |
[ObedientItGuy]: received command [Command(Make me a Sandwich)]...! | |
[ObedientItGuy]: I am so obedient I will do it NOW... | |
[RebelItGuy]: received command [Command(Make me a Sandwich)]... but FYou System! | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: Good boy [ObedientItGuy]... I got your response [[ObedientItGuy] I executed your command [Make me a Sandwich], Me Lord] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: Good boy [RebelItGuy]... I got your response [I executed your command [Make me a Sandwich] after 3 attempts. My family got the message, Me Lord] | |
Terminating... | |
Process finished with exit code 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////// | |
// Here we can appreciate that the answer message of the obedient guy is received // | |
// earlier than the other messages, compared to the "Sample-Output-1.txt" // | |
////////////////////////////////////////////////////////////////////////////////////// | |
[RebelItGuy] Going wild... | |
Here we go | |
[TheBoss] Sending command [Command(Make me a Sandwich)] to [Actor[akka://RebelAkktorsSystem/user/ObedientItGuy#1480100196]] | |
[TheBoss] Sending command [Command(Make me a Sandwich)] to [Actor[akka://RebelAkktorsSystem/user/RebelItGuy#1273867621]] | |
[ObedientItGuy]: received command [Command(Make me a Sandwich)]...! | |
[ObedientItGuy]: I am so obedient I will do it NOW... | |
[RebelItGuy]: received command [Command(Make me a Sandwich)]... but FYou System! | |
[TheBoss]: Good boy [ObedientItGuy]... I got your response [[ObedientItGuy] I executed your command [Make me a Sandwich], Me Lord] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: What, [RebelItGuy]??? F* to me? F* To you! | |
[TheBoss]: Sending Sudo version... of [Command(Make me a Sandwich)] to [RebelItGuy] | |
[TheBoss]: Good boy [RebelItGuy]... I got your response [I executed your command [Make me a Sandwich] after 3 attempts. My family got the message, Me Lord] | |
Terminating... | |
Process finished with exit code 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment