Skip to content

Commit

Permalink
Added PiApproximation example using TypedActors.
Browse files Browse the repository at this point in the history
  • Loading branch information
gvolpe committed Aug 7, 2016
1 parent b1bdfb5 commit b2c7ac3
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 40 deletions.
24 changes: 24 additions & 0 deletions src/main/scala/com/gvolpe/typed/app/Pi.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.gvolpe.typed.app

import akka.actor.ActorSystem
import com.gvolpe.typed.app.actor.{Listener, Master}
import com.gvolpe.typed.app.messages.Calculate
import de.knutwalker.akka.typed._

object Pi extends App {

calculate(nrOfWorkers = 4, nrOfElements = 10000, nrOfMessages = 10000)

def calculate(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int): Unit = {

implicit val system = ActorSystem("PiSystem")

val listener = ActorOf(Listener.props, name = "listener")

val master = ActorOf(Master.props(nrOfWorkers, nrOfElements, nrOfMessages, listener), name = "master")

master ! Calculate

}

}
19 changes: 19 additions & 0 deletions src/main/scala/com/gvolpe/typed/app/actor/Listener.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.gvolpe.typed.app.actor

import com.gvolpe.typed.app.messages.PiApproximation
import de.knutwalker.akka.typed._

object Listener {
def props = PropsFor[Listener]
}

class Listener extends TypedActor.Of[PiApproximation] {

override def typedReceive: TypedReceive = {
case PiApproximation(pi, duration) =>
println("\n\tPi approximation: \t\t%s\n\tCalculation time: \t%s ms"
.format(pi, duration))
context.system.terminate()
}

}
40 changes: 40 additions & 0 deletions src/main/scala/com/gvolpe/typed/app/actor/Master.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.gvolpe.typed.app.actor

import akka.routing.{ActorRefRoutee, RoundRobinRoutingLogic, Router}
import com.gvolpe.typed.app.messages._
import de.knutwalker.akka.typed._

object Master {
def props(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int, listener: ActorRef[PiApproximation]) =
PropsFor(new Master(nrOfWorkers, nrOfElements, nrOfMessages, listener))
}

class Master(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int, listener: ActorRef[PiApproximation]) extends TypedActor.Of[PiMessage] {

var pi: Double = _
var nrOfResults: Int = _
val start: Long = System.currentTimeMillis

val workerRouter: Router = {
val routees = Vector.fill(5) {
val r = ActorOf(Worker.props).untyped
context watch r
ActorRefRoutee(r)
}
Router(RoundRobinRoutingLogic(), routees)
}

override def typedReceive: TypedReceive = {
case Calculate =>
for (i 0 until nrOfMessages) workerRouter.route(Work(i * nrOfElements, nrOfElements), self)
case Result(value) =>
pi += value
nrOfResults += 1
if (nrOfResults == nrOfMessages) {
listener ! PiApproximation(pi, duration = System.currentTimeMillis - start)
// Stops this actor and all its supervised children
context.stop(self)
}
}

}
24 changes: 24 additions & 0 deletions src/main/scala/com/gvolpe/typed/app/actor/Worker.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.gvolpe.typed.app.actor

import com.gvolpe.typed.app.messages.{Result, Work}
import de.knutwalker.akka.typed._

object Worker {
def props = PropsFor[Worker]
}

class Worker extends TypedActor.Of[Work] {

private def calculatePiFor(start: Int, nrOfElements: Int): Double = {
var acc = 0.0
for (i start until (start + nrOfElements))
acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1)
acc
}

override def typedReceive: TypedReceive = {
case Work(start, nrOfElements) =>
sender ! Result(calculatePiFor(start, nrOfElements))
}

}
13 changes: 13 additions & 0 deletions src/main/scala/com/gvolpe/typed/app/messages.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gvolpe.typed.app

object messages {

sealed trait PiMessage extends Product with Serializable
case object Calculate extends PiMessage
final case class Result(value: Double) extends PiMessage

final case class Work(start: Int, nrOfElements: Int)

final case class PiApproximation(pi: Double, duration: Long)

}
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
package com.gvolpe.typed
package com.gvolpe.typed.examples

import akka.actor._
import com.gvolpe.typed.actor.SimpleAkkaActor.{SimpleMessage, SimpleMessageOne, SimpleMessageTwo}
import de.knutwalker.akka.typed.{ActorRef, _}
import com.gvolpe.typed.actor._
import com.gvolpe.typed.actor.SimpleTypedActor._
import com.gvolpe.typed.actor.StrictTypedActor.StrictOne
import com.gvolpe.typed.actor.UnionTypedActor._
import akka.actor.ActorSystem
import com.gvolpe.typed.examples.actor.SimpleAkkaActor.{SimpleMessage, SimpleMessageOne, SimpleMessageTwo}
import com.gvolpe.typed.examples.actor.SimpleTypedActor.{Bar, Foo}
import com.gvolpe.typed.examples.actor.StrictTypedActor.StrictOne
import com.gvolpe.typed.examples.actor.UnionTypedActor.{SampleOne, SampleThree, SampleTwo}
import com.gvolpe.typed.examples.actor._
import de.knutwalker.akka.typed._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

object Demo extends App {

implicit val system = ActorSystem("typed-actors-demo")

case object SomeOtherMessage

val actor = SimpleTypedActor.props
val actor = ActorOf(SimpleTypedActor.props, name = "simple-typed-actor")

actor ! Foo("Hey you be strict!")
actor ! Bar("What's the craic?")

// You'll get a compilation error!
// actor ! SomeOtherMessage

val unionActor = UnionTypedActor.props
val unionActor = ActorOf(UnionTypedActor.props)

unionActor ! SampleOne(5)
unionActor ! SampleTwo("Hey!")
Expand All @@ -43,7 +43,7 @@ object Demo extends App {
// You'll get a compilation error!
// sampleTwoOnlyActor ! SampleOne(1)

val simpleAkkaActor: UntypedActorRef = SimpleAkkaActor.props
val simpleAkkaActor: UntypedActorRef = system.actorOf(SimpleAkkaActor.props)

simpleAkkaActor ! SimpleMessageOne("Hey!")
simpleAkkaActor ! "Whatever, it's untyped!"
Expand All @@ -55,14 +55,14 @@ object Demo extends App {
// You'll get a compilation error!
// simpleAkkaActorTyped ! "Now it will fail!"

val strictTypedActor = StrictTypedActor.props
val strictTypedActor = ActorOf(StrictTypedActor.props, name = "StrictTypedActor")

strictTypedActor ! StrictOne

// You'll get a compilation error!
// strictTypedActor ! "Whatever"

val strictUnionTypedActor = StrictUnionTypedActor.props
val strictUnionTypedActor = ActorOf(StrictUnionTypedActor.props)

strictUnionTypedActor ! StrictUnionTypedActor.Foo()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.gvolpe.typed
package com.gvolpe.typed.examples

import akka.actor.ActorSystem
import com.gvolpe.typed.actor.ReplyToPatternActor
import de.knutwalker.akka.typed._
import com.gvolpe.typed.examples.actor.ReplyToPatternActor
import de.knutwalker.akka.typed.{Typed, _}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

object ReplyToPatternDemo extends App {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import com.gvolpe.typed.ReplyToPatternDemo.{MyMessage, MyResponse}
import com.gvolpe.typed.examples.ReplyToPatternDemo.{MyMessage, MyResponse}
import de.knutwalker.akka.typed._

case class ReplyToPatternActor() extends TypedActor.Of[MyMessage] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import akka.actor.{Actor, ActorSystem, Props}
import com.gvolpe.typed.actor.SimpleAkkaActor.{SimpleMessageOne, SimpleMessageTwo}
import akka.actor.{Actor, Props}
import com.gvolpe.typed.examples.actor.SimpleAkkaActor.{SimpleMessageOne, SimpleMessageTwo}

object SimpleAkkaActor {
sealed trait SimpleMessage
case class SimpleMessageOne(v: String) extends SimpleMessage
case class SimpleMessageTwo(v: String) extends SimpleMessage

def props(implicit s: ActorSystem) = s.actorOf(Props[SimpleAkkaActor])
def props = Props[SimpleAkkaActor]
}

class SimpleAkkaActor extends Actor {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import akka.actor.{Actor, ActorSystem}
import akka.actor.Actor
import de.knutwalker.akka.typed._
import com.gvolpe.typed.actor.SimpleTypedActor._
import com.gvolpe.typed.examples.actor.SimpleTypedActor._

object SimpleTypedActor {
sealed trait MyMessage
case class Foo(foo: String) extends MyMessage
case class Bar(bar: String) extends MyMessage

def props(implicit s: ActorSystem) = ActorOf(Props[MyMessage, SimpleTypedActor], name = "typed-actor")
def props = Props[MyMessage, SimpleTypedActor]
}

class SimpleTypedActor extends Actor {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import akka.actor.ActorSystem
import com.gvolpe.typed.actor.StrictTypedActor._
import com.gvolpe.typed.examples.actor.StrictTypedActor._
import de.knutwalker.akka.typed._

object StrictTypedActor {
Expand All @@ -11,7 +10,7 @@ object StrictTypedActor {

case object NotStrict

def props(implicit s: ActorSystem) = ActorOf(Props[StrictMessage, StrictTypedActor], name = "StrictTypedActor")
def props = Props[StrictMessage, StrictTypedActor]
}

class StrictTypedActor extends TypedActor.Of[StrictMessage] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import akka.actor.ActorSystem
import com.gvolpe.typed.actor.StrictUnionTypedActor._
import com.gvolpe.typed.examples.actor.StrictUnionTypedActor._
import de.knutwalker.akka.typed._

object StrictUnionTypedActor {
Expand All @@ -10,7 +9,7 @@ object StrictUnionTypedActor {
case class Baz()

// Message type derivation using PropsFor (only for typed actor)
def props(implicit s: ActorSystem) = ActorOf(PropsFor[StrictUnionTypedActor]).or[Bar].or[Baz]
def props = PropsFor[StrictUnionTypedActor]
}

// NOTE: It doesn't allow case objects as types
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.gvolpe.typed.actor
package com.gvolpe.typed.examples.actor

import akka.actor.{Actor, ActorSystem}
import akka.actor.Actor
import de.knutwalker.akka.typed._
import com.gvolpe.typed.actor.UnionTypedActor._
import com.gvolpe.typed.examples.actor.UnionTypedActor._

object UnionTypedActor {
case class SampleOne(n: Int)
case class SampleTwo(v: String)
case class SampleThree(b: Boolean)

def props(implicit s: ActorSystem) = ActorOf(Props[SampleOne, UnionTypedActor]).or[SampleTwo].or[SampleThree]
def props = Props[SampleOne, UnionTypedActor].or[SampleTwo].or[SampleThree]
}

class UnionTypedActor extends Actor {
Expand Down

0 comments on commit b2c7ac3

Please sign in to comment.