├── .gitignore ├── README.md ├── build.sbt ├── console └── src │ └── main │ ├── resources │ └── application.conf │ └── scala │ ├── ConsoleMain.scala │ └── victorops │ └── example │ └── Console.scala ├── counter └── src │ └── main │ ├── resources │ └── application.conf │ └── scala │ ├── CounterMain.scala │ └── victorops │ └── example │ └── CountingActor.scala └── project └── build.properties /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.class 3 | *.log 4 | 5 | # sbt specific 6 | .cache 7 | .history 8 | .lib/ 9 | dist/* 10 | target/ 11 | lib_managed/ 12 | src_managed/ 13 | project/boot/ 14 | project/plugins/project/ 15 | 16 | # Scala-IDE specific 17 | .scala_dependencies 18 | .worksheet 19 | 20 | # ENSIME specific 21 | .ensime_cache/ 22 | .ensime 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VictorOps Akka Console Example 2 | 3 | This is a thing we use here at VictorOps, and it's awesome. 4 | 5 | ## Run the example 6 | 7 | ``` 8 | $ git clone https://github.com/victorops/akka-console-example.git 9 | ``` 10 | 11 | In terminal one: 12 | 13 | ``` 14 | $ cd akka-console-example 15 | $ sbt counter/run 16 | ``` 17 | 18 | In terminal two: 19 | 20 | ``` 21 | $ cd akka-console-example 22 | $ sbt console/run 23 | ``` 24 | 25 | In the ammonite REPL: 26 | 27 | ``` 28 | @ getCount 29 | @ incrementCount 30 | @ resetCount 31 | ``` 32 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | name := "victorops-akka-repl" 2 | 3 | val ScalaVersion = "2.11.8" 4 | val AkkaVersion = "2.4.11" 5 | val Ammoniteversion = "1.0.3" 6 | 7 | lazy val commonSettings = Seq( 8 | organization := "victorops", 9 | version := "1.0.0", 10 | scalaVersion := ScalaVersion, 11 | javacOptions in Compile ++= Seq("-source", "1.8", "-target", "1.8"), 12 | ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) } 13 | ) 14 | 15 | lazy val root = (project in file(".")) 16 | .aggregate(console, counter) 17 | 18 | lazy val counter = (project in file("counter")) 19 | .settings(commonSettings ++ Seq( 20 | libraryDependencies ++= Seq( 21 | "com.typesafe.akka" %% "akka-actor" % AkkaVersion, 22 | "com.typesafe.akka" %% "akka-remote" % AkkaVersion, 23 | "com.typesafe.akka" %% "akka-testkit" % AkkaVersion % "test" 24 | ) 25 | ):_*) 26 | 27 | lazy val console = (project in file("console")) 28 | .dependsOn(counter) 29 | .settings(commonSettings ++ Seq( 30 | libraryDependencies ++= Seq( 31 | // needed when ammonite is in an sbt module... 32 | "org.scala-lang" % "scala-library" % ScalaVersion, 33 | 34 | "com.lihaoyi" % "ammonite" % Ammoniteversion cross CrossVersion.full 35 | ) 36 | ):_*) 37 | -------------------------------------------------------------------------------- /console/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | akka { 2 | actor { 3 | provider = remote 4 | warn-about-java-serializer-usage = off 5 | } 6 | remote { 7 | enabled-transports = ["akka.remote.netty.tcp"] 8 | netty.tcp { 9 | hostname = "127.0.0.1" 10 | port = 2553 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /console/src/main/scala/ConsoleMain.scala: -------------------------------------------------------------------------------- 1 | import akka.actor.ActorSystem 2 | import victorops.example.Console 3 | 4 | object ConsoleMain { 5 | def main(args: Array[String]): Unit = { 6 | 7 | val system = ActorSystem("ConsoleActorSystem") 8 | val console = new Console(system) 9 | 10 | ammonite.Main( 11 | predefCode = 12 | """ 13 | |println("Loading the VictorOps Example Console!") 14 | |import console.imports._ 15 | """.stripMargin 16 | ).run( 17 | "console" -> console 18 | ) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /console/src/main/scala/victorops/example/Console.scala: -------------------------------------------------------------------------------- 1 | package victorops.example 2 | 3 | import akka.actor.{ ActorSelection, ActorSystem } 4 | import akka.pattern._ 5 | import akka.util.Timeout 6 | import victorops.example.Console.Imports 7 | import victorops.example.CountingActor.{ GetCount, IncrementCount, ResetCount } 8 | 9 | import scala.concurrent.duration._ 10 | import scala.concurrent.{ Await, Future } 11 | 12 | trait CountingTasks { 13 | 14 | implicit def timeout: Timeout 15 | 16 | def system: ActorSystem 17 | 18 | def countingActor: ActorSelection 19 | 20 | def getCount(): Int = awaitResult { 21 | (countingActor ? GetCount).mapTo[Int] 22 | } 23 | 24 | def incrementCount(): Int = awaitResult { 25 | (countingActor ? IncrementCount).mapTo[Int] 26 | } 27 | 28 | def resetCount(): Int = awaitResult { 29 | (countingActor ? ResetCount).mapTo[Int] 30 | } 31 | 32 | private def awaitResult[T](f: Future[T]) = Await.result(f, Duration.Inf) 33 | } 34 | 35 | object Console { 36 | class Imports(val system: ActorSystem) 37 | } 38 | 39 | class Console(system: ActorSystem) { 40 | object imports extends Imports(system) with CountingTasks { 41 | implicit val timeout = Timeout(1 second) 42 | 43 | lazy val countingActor: ActorSelection = { 44 | system.actorSelection("akka.tcp://CounterActorSystem@127.0.0.1:2552/user/counting-actor") 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /counter/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | akka { 2 | actor { 3 | provider = remote 4 | warn-about-java-serializer-usage = off 5 | } 6 | remote { 7 | enabled-transports = ["akka.remote.netty.tcp"] 8 | netty.tcp { 9 | hostname = "127.0.0.1" 10 | port = 2552 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /counter/src/main/scala/CounterMain.scala: -------------------------------------------------------------------------------- 1 | import akka.actor.{ ActorSystem, Props } 2 | import victorops.example.CountingActor 3 | 4 | object CounterMain extends App { 5 | 6 | val system = ActorSystem("CounterActorSystem") 7 | 8 | val countingActor = system.actorOf(Props(classOf[CountingActor]), "counting-actor") 9 | 10 | system.awaitTermination() 11 | 12 | } 13 | -------------------------------------------------------------------------------- /counter/src/main/scala/victorops/example/CountingActor.scala: -------------------------------------------------------------------------------- 1 | package victorops.example 2 | 3 | import java.util.concurrent.atomic.AtomicInteger 4 | 5 | import akka.actor.{ Actor, ActorLogging } 6 | import victorops.example.CountingActor.{ GetCount, IncrementCount, ResetCount } 7 | 8 | object CountingActor { 9 | case object GetCount 10 | case object IncrementCount 11 | case object ResetCount 12 | } 13 | 14 | class CountingActor extends Actor with ActorLogging { 15 | private val count = new AtomicInteger(0) 16 | 17 | override def receive: Receive = { 18 | case GetCount => 19 | sender() ! count.get() 20 | log.info(s"Got GetCount [count=$count]") 21 | 22 | case IncrementCount => 23 | sender() ! count.incrementAndGet() 24 | log.info(s"Got IncrementCount [count=$count]") 25 | 26 | case ResetCount => 27 | sender() ! count.getAndSet(0) 28 | log.info(s"Got ResetCount [count=$count]") 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.16 2 | --------------------------------------------------------------------------------