From 14eaf423f0a22d88cdf346f38877278cce2a84b6 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Thu, 13 Aug 2020 22:47:27 +0530 Subject: [PATCH] first commit --- ActorDemo.sc | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE | 20 +++++++++++ README.md | 17 ++++++++++ 3 files changed, 130 insertions(+) create mode 100755 ActorDemo.sc create mode 100644 LICENSE create mode 100644 README.md diff --git a/ActorDemo.sc b/ActorDemo.sc new file mode 100755 index 0000000..d3d996b --- /dev/null +++ b/ActorDemo.sc @@ -0,0 +1,93 @@ +#!/usr/bin/env amm + +import $ivy.`com.typesafe.akka::akka-actor-typed:2.6.8` +import $ivy.`ch.qos.logback:logback-classic:1.2.3` + +import akka.actor.typed.delivery.ConsumerController.Command +import akka.actor.Actor +import akka.actor.typed.ActorRef +import akka.actor.typed.ActorSystem +import akka.actor.typed.Behavior +import akka.actor.typed.scaladsl.Behaviors +import akka.util.Timeout +import scala.concurrent.duration._ +import akka.actor.typed.scaladsl.AskPattern._ +import scala.concurrent.ExecutionContext.Implicits.global + +object CounterActor { + sealed trait Command + final case object IncCount extends Command + final case class CounterResult(count: Int) + final case class GetResult(sender: ActorRef[RootActor.Command]) + extends Command + + var counter = 0 + + def apply(): Behavior[Command] = + Behaviors.receive { (context, command) => + command match { + case IncCount => counter += 1 + case GetResult(sender) => + context.log.info(s"Value of counter is $counter"); + sender ! RootActor.Reply(counter) + } + + Behaviors.same + } + +} + +object RootActor { + sealed trait Command + case class Reply[T](reply: T) extends Command + case object Begin extends Command + case object GetResult extends Command + + implicit val timeout: Timeout = 3.seconds + + def apply(): Behavior[Command] = + Behaviors.setup { context => + implicit val system = context.system + + val counterActor = context.spawn(CounterActor(), "counterActor") + + Behaviors.receiveMessage { message => + message match { + case Reply(reply) => context.log.info(s"Received message $message") + case Begin => + context.log.info("--- Beginning ---") + + counterActor ! CounterActor.IncCount + counterActor ! CounterActor.IncCount + counterActor ! CounterActor.IncCount + counterActor ! CounterActor.IncCount + counterActor ! CounterActor.IncCount + + case GetResult => + counterActor ! CounterActor.GetResult( + context.self + ) + } + + Behaviors.same + } + + } +} + +@main +def main() = { + val t = new Thread(() => { + implicit val rootActor = + ActorSystem(RootActor(), "TestActors") + + implicit val timeout: Timeout = 3.seconds + + rootActor ! RootActor.Begin + rootActor ! RootActor.GetResult + }) + t.setDaemon(true) + t.start() + Thread.sleep(1000) + System.exit(0) +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..24a8f90 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute +this software, either in source code form or as a compiled binary, for any +purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and +to the detriment of our heirs and successors. We intend this dedication to +be an overt act of relinquishment in perpetuity of all present and future +rights to this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, +please refer to diff --git a/README.md b/README.md new file mode 100644 index 0000000..5cb088b --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Akka Actors Demo + +An experiment to see how the actor model can be used to synchronize / encapsulate mutable state without the use of locks. + +## Usage +``` bash +./ActorsDemo.sc +``` + +Sample output: +``` +22:11:47.473 [TestActors-akka.actor.default-dispatcher-3] INFO ammonite.$file.ActorDemo$RootActor$ - --- Beginning --- + +22:11:47.475 [TestActors-akka.actor.default-dispatcher-6] INFO ammonite.$file.ActorDemo$CounterActor$ - Value of counter is 5 + +22:11:47.475 [TestActors-akka.actor.default-dispatcher-3] INFO ammonite.$file.ActorDemo$RootActor$ - Received message Reply(5) +``` \ No newline at end of file