diff --git a/akka-actor/src/main/scala/akka/routing/ConnectionManager.scala b/akka-actor/src/main/scala/akka/routing/ConnectionManager.scala index b7655e376e..e8649dc3db 100644 --- a/akka-actor/src/main/scala/akka/routing/ConnectionManager.scala +++ b/akka-actor/src/main/scala/akka/routing/ConnectionManager.scala @@ -11,6 +11,7 @@ import scala.annotation.tailrec import java.util.concurrent.atomic.{ AtomicReference, AtomicInteger } import java.net.InetSocketAddress import akka.remote.RemoteAddress +import collection.JavaConverters /** * An Iterable that also contains a version. @@ -85,6 +86,10 @@ trait ConnectionManager { */ class LocalConnectionManager(initialConnections: Iterable[ActorRef]) extends ConnectionManager { + def this(linkedList: java.util.LinkedList[ActorRef]) { + this(JavaConverters.iterableAsScalaIterableConverter(linkedList).asScala) + } + case class State(version: Long, connections: Iterable[ActorRef]) extends VersionedIterable[ActorRef] { def iterable = connections } diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index 0dc6366cb1..8257002a42 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -14,6 +14,7 @@ import java.lang.reflect.InvocationTargetException import java.util.concurrent.atomic.{ AtomicReference, AtomicInteger } import scala.annotation.tailrec +import akka.japi.Creator sealed trait RouterType @@ -66,11 +67,17 @@ object RouterType { * Contains the configuration to create local and clustered routed actor references. * Routed ActorRef configuration object, this is thread safe and fully sharable. */ -case class RoutedProps private[akka] ( +private[akka] case class RoutedProps( routerFactory: () ⇒ Router = RoutedProps.defaultRouterFactory, connectionManager: ConnectionManager = new LocalConnectionManager(List()), timeout: Timeout = RoutedProps.defaultTimeout, localOnly: Boolean = RoutedProps.defaultLocalOnly) { + + // Java API + def this(creator: Creator[Router], connectionManager: ConnectionManager, timeout: Timeout, localOnly: Boolean) { + this(() ⇒ creator.create(), connectionManager, timeout, localOnly) + } + } object RoutedProps { @@ -167,7 +174,7 @@ abstract private[akka] class AbstractRoutedActorRef(val system: ActorSystem, val * A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to send a message to * on (or more) of these actors. */ -private[akka] class RoutedActorRef(system: ActorSystem, val routedProps: RoutedProps, val supervisor: ActorRef, override val name: String) extends AbstractRoutedActorRef(system, routedProps) { +class RoutedActorRef(system: ActorSystem, val routedProps: RoutedProps, val supervisor: ActorRef, override val name: String) extends AbstractRoutedActorRef(system, routedProps) { val path = supervisor.path / name @@ -346,7 +353,7 @@ class RandomRouter extends BasicRouter { * * @author Jonas Bonér */ -class RoundRobinRouter extends BasicRouter { +private[akka] class RoundRobinRouter extends BasicRouter { private val state = new AtomicReference[RoundRobinState] diff --git a/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala b/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala index eedf58fd9e..9424b93372 100644 --- a/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala +++ b/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala @@ -95,8 +95,8 @@ abstract class RemoteClient private[akka] ( } class PassiveRemoteClient(val currentChannel: Channel, - remoteSupport: NettyRemoteSupport, - remoteAddress: RemoteAddress) + remoteSupport: NettyRemoteSupport, + remoteAddress: RemoteAddress) extends RemoteClient(remoteSupport, remoteAddress) { def connect(reconnectIfAlreadyConnected: Boolean = false): Boolean = runSwitch switchOn { diff --git a/akka-remote/src/test/scala/akka/remote/NetworkFailureSpec.scala b/akka-remote/src/test/scala/akka/remote/NetworkFailureSpec.scala index 7f7072b427..56a27079ea 100644 --- a/akka-remote/src/test/scala/akka/remote/NetworkFailureSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/NetworkFailureSpec.scala @@ -20,7 +20,7 @@ trait NetworkFailureSpec { self: AkkaSpec ⇒ val BytesPerSecond = "60KByte/s" val DelayMillis = "350ms" - val PortRang = "1024-65535" + val PortRange = "1024-65535" def replyWithTcpResetFor(duration: Duration, dead: AtomicBoolean) = { Future { @@ -82,12 +82,12 @@ trait NetworkFailureSpec { self: AkkaSpec ⇒ def enableNetworkDrop() = { restoreIP() - assert(new ProcessBuilder("ipfw", "add", "1", "deny", "tcp", "from", "any", "to", "any", PortRang).start.waitFor == 0) + assert(new ProcessBuilder("ipfw", "add", "1", "deny", "tcp", "from", "any", "to", "any", PortRange).start.waitFor == 0) } def enableTcpReset() = { restoreIP() - assert(new ProcessBuilder("ipfw", "add", "1", "reset", "tcp", "from", "any", "to", "any", PortRang).start.waitFor == 0) + assert(new ProcessBuilder("ipfw", "add", "1", "reset", "tcp", "from", "any", "to", "any", PortRange).start.waitFor == 0) } def restoreIP() = { diff --git a/akka-samples/akka-sample-ants/README.md b/akka-samples/akka-sample-ants/README.md index 3c559834cb..5a416e0ba4 100644 --- a/akka-samples/akka-sample-ants/README.md +++ b/akka-samples/akka-sample-ants/README.md @@ -39,8 +39,8 @@ By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software. -[ants.clj]:http://clojure.googlegroups.com/web/ants.clj -[akka]:http://akkasource.org -[spde]:http://technically.us/spde/ +[ants.clj]: http://clojure.googlegroups.com/web/ants.clj +[akka]: http://akka.io +[spde]: http://technically.us/spde/ [sbt]: http://code.google.com/p/simple-build-tool/ [cpl]: http://opensource.org/licenses/cpl1.0.php \ No newline at end of file diff --git a/akka-samples/akka-sample-ants/src/main/scala/Ants.scala b/akka-samples/akka-sample-ants/src/main/scala/Ants.scala index a6aae6f8bd..4b9cd8dd88 100644 --- a/akka-samples/akka-sample-ants/src/main/scala/Ants.scala +++ b/akka-samples/akka-sample-ants/src/main/scala/Ants.scala @@ -4,22 +4,23 @@ package sample.ants +import scala.util.Random.{ nextInt ⇒ randomInt } +import akka.actor.{ ActorSystem, Actor, ActorRef } +import akka.util.Duration +import akka.util.duration._ import java.util.concurrent.TimeUnit -import scala.util.Random.{nextInt => randomInt} -import akka.actor.{Actor, ActorRef, Scheduler} -import akka.actor.Actor.actorOf import akka.stm._ object Config { - val Dim = 80 // dimensions of square world - val AntsSqrt = 20 // number of ants = AntsSqrt^2 - val FoodPlaces = 35 // number of places with food - val FoodRange = 100 // range of amount of food at a place - val PherScale = 10 // scale factor for pheromone drawing - val AntMillis = 100 // how often an ant behaves (milliseconds) - val EvapMillis = 1000 // how often pheromone evaporation occurs (milliseconds) - val EvapRate = 0.99f // pheromone evaporation rate - val StartDelay = 1000 // delay before everything kicks off (milliseconds) + val Dim = 80 // dimensions of square world + val AntsSqrt = 20 // number of ants = AntsSqrt^2 + val FoodPlaces = 35 // number of places with food + val FoodRange = 100 // range of amount of food at a place + val PherScale = 10 // scale factor for pheromone drawing + val AntMillis = 100 // how often an ant behaves (milliseconds) + val EvapMillis = 1000 // how often pheromone evaporation occurs (milliseconds) + val EvapRate = 0.99f // pheromone evaporation rate + val StartDelay = 1000 milliseconds // delay before everything kicks off (milliseconds) } case class Ant(dir: Int, food: Boolean = false) { @@ -32,7 +33,7 @@ case class Ant(dir: Int, food: Boolean = false) { case class Cell(food: Int = 0, pher: Float = 0, ant: Option[Ant] = None, home: Boolean = false) { def addFood(i: Int) = copy(food = food + i) def addPher(x: Float) = copy(pher = pher + x) - def alterPher(f: Float => Float) = copy(pher = f(pher)) + def alterPher(f: Float ⇒ Float) = copy(pher = f(pher)) def putAnt(antOpt: Option[Ant]) = copy(ant = antOpt) def makeHome = copy(home = true) } @@ -45,10 +46,10 @@ class Place(initCell: Cell = EmptyCell) extends Ref(initCell) { def food(i: Int) = alter(_.addFood(i)) def hasFood = food > 0 def pher: Float = cell.pher - def pher(f: Float => Float) = alter(_.alterPher(f)) + def pher(f: Float ⇒ Float) = alter(_.alterPher(f)) def trail = alter(_.addPher(1)) def ant: Option[Ant] = cell.ant - def ant(f: Ant => Ant): Cell = alter(_.putAnt(ant map f)) + def ant(f: Ant ⇒ Ant): Cell = alter(_.putAnt(ant map f)) def enter(antOpt: Option[Ant]): Cell = alter(_.putAnt(antOpt)) def enter(ant: Ant): Cell = enter(Some(ant)) def leave = enter(None) @@ -62,10 +63,12 @@ case object Ping object World { import Config._ + val system = ActorSystem() + val homeOff = Dim / 4 lazy val places = Vector.fill(Dim, Dim)(new Place) lazy val ants = setup - lazy val evaporator = actorOf[Evaporator] + lazy val evaporator = system.actorOf[Evaporator] private val snapshotFactory = TransactionFactory(readonly = true, familyName = "snapshot") @@ -74,14 +77,14 @@ object World { def place(loc: (Int, Int)) = places(loc._1)(loc._2) private def setup = atomic { - for (i <- 1 to FoodPlaces) { + for (i ← 1 to FoodPlaces) { place(randomInt(Dim), randomInt(Dim)) food (randomInt(FoodRange)) } val homeRange = homeOff until (AntsSqrt + homeOff) - for (x <- homeRange; y <- homeRange) yield { + for (x ← homeRange; y ← homeRange) yield { place(x, y).makeHome place(x, y) enter Ant(randomInt(8)) - actorOf(new AntActor(x, y)) + system.actorOf(new AntActor(x, y)) } } @@ -91,7 +94,7 @@ object World { } private def pingEvery(millis: Long)(actor: ActorRef) = - Scheduler.schedule(actor, Ping, Config.StartDelay, millis, TimeUnit.MILLISECONDS) + system.scheduler.schedule(actor, Ping, Config.StartDelay, Duration(millis, TimeUnit.MILLISECONDS)) } object Util { @@ -106,13 +109,13 @@ object Util { def dimBound(n: Int) = bound(Dim, n) val dirDelta = Map(0 -> (0, -1), 1 -> (1, -1), 2 -> (1, 0), 3 -> (1, 1), - 4 -> (0, 1), 5 -> (-1, 1), 6 -> (-1, 0), 7 -> (-1, -1)) + 4 -> (0, 1), 5 -> (-1, 1), 6 -> (-1, 0), 7 -> (-1, -1)) def deltaLoc(x: Int, y: Int, dir: Int) = { val (dx, dy) = dirDelta(dirBound(dir)) (dimBound(x + dx), dimBound(y + dy)) } - def rankBy[A, B: Ordering](xs: Seq[A], f: A => B) = Map(xs.sortBy(f).zip(Stream from 1): _*) + def rankBy[A, B: Ordering](xs: Seq[A], f: A ⇒ B) = Map(xs.sortBy(f).zip(Stream from 1): _*) def roulette(slices: Seq[Int]) = { val total = slices.sum @@ -128,7 +131,7 @@ object Util { trait WorldActor extends Actor { def act - def receive = { case Ping => act } + def receive = { case Ping ⇒ act } } class AntActor(initLoc: (Int, Int)) extends WorldActor { @@ -140,8 +143,8 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor { val name = "ant-from-" + initLoc._1 + "-" + initLoc._2 implicit val txFactory = TransactionFactory(familyName = name) - val homing = (p: Place) => p.pher + (100 * (if (p.home) 0 else 1)) - val foraging = (p: Place) => p.pher + p.food + val homing = (p: Place) ⇒ p.pher + (100 * (if (p.home) 0 else 1)) + val foraging = (p: Place) ⇒ p.pher + p.food def loc = locRef.getOrElse(initLoc) def newLoc(l: (Int, Int)) = locRef swap l @@ -149,7 +152,7 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor { def act = atomic { val (x, y) = loc val current = place(x, y) - for (ant <- current.ant) { + for (ant ← current.ant) { val ahead = place(deltaLoc(x, y, ant.dir)) if (ant.food) { // homing if (current.home) dropFood @@ -166,7 +169,7 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor { def move = { val (x, y) = loc val from = place(x, y) - for (ant <- from.ant) { + for (ant ← from.ant) { val toLoc = deltaLoc(x, y, ant.dir) val to = place(toLoc) to enter ant @@ -188,11 +191,11 @@ class AntActor(initLoc: (Int, Int)) extends WorldActor { current ant (_.dropOff.turnAround) } - def random[A: Ordering](ranking: Place => A) = { + def random[A: Ordering](ranking: Place ⇒ A) = { val (x, y) = loc val current = place(x, y) - for (ant <- current.ant) { - val delta = (turn: Int) => place(deltaLoc(x, y, ant.dir + turn)) + for (ant ← current.ant) { + val delta = (turn: Int) ⇒ place(deltaLoc(x, y, ant.dir + turn)) val ahead = delta(0) val aheadLeft = delta(-1) val aheadRight = delta(+1) @@ -211,9 +214,9 @@ class Evaporator extends WorldActor { import World._ implicit val txFactory = TransactionFactory(familyName = "evaporator") - val evaporate = (pher: Float) => pher * EvapRate + val evaporate = (pher: Float) ⇒ pher * EvapRate - def act = for (x <- 0 until Dim; y <- 0 until Dim) { + def act = for (x ← 0 until Dim; y ← 0 until Dim) { atomic { place(x, y) pher evaporate } } } diff --git a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Actors.scala b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Actors.scala index f4655c3985..c091d7dfd8 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Actors.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Actors.scala @@ -1,161 +1,167 @@ -package sample.camel - -import org.apache.camel.Exchange - -import akka.actor.{ Actor, ActorRef, ActorRegistry } -import akka.camel.{ Ack, Failure, Producer, Message, Consumer } - /** - * Client-initiated remote actor. - */ -class RemoteActor1 extends Actor with Consumer { - def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-1" + * Copyright (C) 2009-2010 Typesafe Inc. . + */ - protected def receive = { - case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote1")) - } -} +// CAMEL IS NOT PART OF MILESTONE 1 OF AKKA 2.0 -/** - * Server-initiated remote actor. - */ -class RemoteActor2 extends Actor with Consumer { - def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-2" - - protected def receive = { - case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote2")) - } -} - -class Producer1 extends Actor with Producer { - def endpointUri = "direct:welcome" - override def oneway = false // default -} - -class Consumer1 extends Actor with Consumer { - def endpointUri = "file:data/input/actor" - - def receive = { - case msg: Message ⇒ println("received %s" format msg.bodyAs[String]) - } -} - -class Consumer2 extends Actor with Consumer { - def endpointUri = "jetty:http://0.0.0.0:8877/camel/default" - - def receive = { - case msg: Message ⇒ sender ! ("Hello %s" format msg.bodyAs[String]) - } -} - -class Consumer3(transformer: ActorRef) extends Actor with Consumer { - def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome" - - def receive = { - case msg: Message ⇒ transformer.forward(msg.setBodyAs[String]) - } -} - -class Consumer4 extends Actor with Consumer { - def endpointUri = "jetty:http://0.0.0.0:8877/camel/stop" - - def receive = { - case msg: Message ⇒ msg.bodyAs[String] match { - case "stop" ⇒ { - sender ! "Consumer4 stopped" - self.stop - } - case body ⇒ sender ! body - } - } -} - -class Consumer5 extends Actor with Consumer { - def endpointUri = "jetty:http://0.0.0.0:8877/camel/start" - - def receive = { - case _ ⇒ { - Actor.actorOf[Consumer4] - sender ! "Consumer4 started" - } - } -} - -class Transformer(producer: ActorRef) extends Actor { - protected def receive = { - case msg: Message ⇒ producer.forward(msg.transformBody((body: String) ⇒ "- %s -" format body)) - } -} - -class Subscriber(name: String, uri: String) extends Actor with Consumer { - def endpointUri = uri - - protected def receive = { - case msg: Message ⇒ println("%s received: %s" format (name, msg.body)) - } -} - -class Publisher(uri: String) extends Actor with Producer { - def endpointUri = uri - override def oneway = true -} - -class PublisherBridge(uri: String, publisher: ActorRef) extends Actor with Consumer { - def endpointUri = uri - - protected def receive = { - case msg: Message ⇒ { - publisher ! msg.bodyAs[String] - sender ! "message published" - } - } -} - -class HttpConsumer(producer: ActorRef) extends Actor with Consumer { - def endpointUri = "jetty:http://0.0.0.0:8875/" - - protected def receive = { - case msg ⇒ producer forward msg - } -} - -class HttpProducer(transformer: ActorRef) extends Actor with Producer { - def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true" - - override protected def receiveBeforeProduce = { - // only keep Exchange.HTTP_PATH message header (which needed by bridge endpoint) - case msg: Message ⇒ msg.setHeaders(msg.headers(Set(Exchange.HTTP_PATH))) - } - - override protected def receiveAfterProduce = { - // do not reply but forward result to transformer - case msg ⇒ transformer forward msg - } -} - -class HttpTransformer extends Actor { - protected def receive = { - case msg: Message ⇒ sender ! (msg.transformBody { body: String ⇒ body replaceAll ("Akka ", "AKKA ") }) - case msg: Failure ⇒ sender ! msg - } -} - -class FileConsumer extends Actor with Consumer { - def endpointUri = "file:data/input/actor?delete=true" - override def autoack = false - - var counter = 0 - - def receive = { - case msg: Message ⇒ { - if (counter == 2) { - println("received %s" format msg.bodyAs[String]) - sender ! Ack - } else { - println("rejected %s" format msg.bodyAs[String]) - counter += 1 - sender ! Failure(new Exception("message number %s not accepted" format counter)) - } - } - } -} +//package sample.camel +// +//import org.apache.camel.Exchange +// +//import akka.actor.{ Actor, ActorRef, ActorRegistry } +//import akka.camel.{ Ack, Failure, Producer, Message, Consumer } +// +///** +// * Client-initiated remote actor. +// */ +//class RemoteActor1 extends Actor with Consumer { +// def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-1" +// +// protected def receive = { +// case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote1")) +// } +//} +// +///** +// * Server-initiated remote actor. +// */ +//class RemoteActor2 extends Actor with Consumer { +// def endpointUri = "jetty:http://localhost:6644/camel/remote-actor-2" +// +// protected def receive = { +// case msg: Message ⇒ sender ! Message("hello %s" format msg.bodyAs[String], Map("sender" -> "remote2")) +// } +//} +// +//class Producer1 extends Actor with Producer { +// def endpointUri = "direct:welcome" +// override def oneway = false // default +//} +// +//class Consumer1 extends Actor with Consumer { +// def endpointUri = "file:data/input/actor" +// +// def receive = { +// case msg: Message ⇒ println("received %s" format msg.bodyAs[String]) +// } +//} +// +//class Consumer2 extends Actor with Consumer { +// def endpointUri = "jetty:http://0.0.0.0:8877/camel/default" +// +// def receive = { +// case msg: Message ⇒ sender ! ("Hello %s" format msg.bodyAs[String]) +// } +//} +// +//class Consumer3(transformer: ActorRef) extends Actor with Consumer { +// def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome" +// +// def receive = { +// case msg: Message ⇒ transformer.forward(msg.setBodyAs[String]) +// } +//} +// +//class Consumer4 extends Actor with Consumer { +// def endpointUri = "jetty:http://0.0.0.0:8877/camel/stop" +// +// def receive = { +// case msg: Message ⇒ msg.bodyAs[String] match { +// case "stop" ⇒ { +// sender ! "Consumer4 stopped" +// self.stop +// } +// case body ⇒ sender ! body +// } +// } +//} +// +//class Consumer5 extends Actor with Consumer { +// def endpointUri = "jetty:http://0.0.0.0:8877/camel/start" +// +// def receive = { +// case _ ⇒ { +// Actor.actorOf[Consumer4] +// sender ! "Consumer4 started" +// } +// } +//} +// +//class Transformer(producer: ActorRef) extends Actor { +// protected def receive = { +// case msg: Message ⇒ producer.forward(msg.transformBody((body: String) ⇒ "- %s -" format body)) +// } +//} +// +//class Subscriber(name: String, uri: String) extends Actor with Consumer { +// def endpointUri = uri +// +// protected def receive = { +// case msg: Message ⇒ println("%s received: %s" format (name, msg.body)) +// } +//} +// +//class Publisher(uri: String) extends Actor with Producer { +// def endpointUri = uri +// override def oneway = true +//} +// +//class PublisherBridge(uri: String, publisher: ActorRef) extends Actor with Consumer { +// def endpointUri = uri +// +// protected def receive = { +// case msg: Message ⇒ { +// publisher ! msg.bodyAs[String] +// sender ! "message published" +// } +// } +//} +// +//class HttpConsumer(producer: ActorRef) extends Actor with Consumer { +// def endpointUri = "jetty:http://0.0.0.0:8875/" +// +// protected def receive = { +// case msg ⇒ producer forward msg +// } +//} +// +//class HttpProducer(transformer: ActorRef) extends Actor with Producer { +// def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true" +// +// override protected def receiveBeforeProduce = { +// // only keep Exchange.HTTP_PATH message header (which needed by bridge endpoint) +// case msg: Message ⇒ msg.setHeaders(msg.headers(Set(Exchange.HTTP_PATH))) +// } +// +// override protected def receiveAfterProduce = { +// // do not reply but forward result to transformer +// case msg ⇒ transformer forward msg +// } +//} +// +//class HttpTransformer extends Actor { +// protected def receive = { +// case msg: Message ⇒ sender ! (msg.transformBody { body: String ⇒ body replaceAll ("Akka ", "AKKA ") }) +// case msg: Failure ⇒ sender ! msg +// } +//} +// +//class FileConsumer extends Actor with Consumer { +// def endpointUri = "file:data/input/actor?delete=true" +// override def autoack = false +// +// var counter = 0 +// +// def receive = { +// case msg: Message ⇒ { +// if (counter == 2) { +// println("received %s" format msg.bodyAs[String]) +// sender ! Ack +// } else { +// println("rejected %s" format msg.bodyAs[String]) +// counter += 1 +// sender ! Failure(new Exception("message number %s not accepted" format counter)) +// } +// } +// } +//} diff --git a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Boot.scala b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Boot.scala index b84dd9c1c9..31b76835a4 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Boot.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Boot.scala @@ -1,98 +1,104 @@ -package sample.camel - -import org.apache.camel.{ Exchange, Processor } -import org.apache.camel.builder.RouteBuilder -import org.apache.camel.impl.DefaultCamelContext -import org.apache.camel.spring.spi.ApplicationContextRegistry -import org.springframework.context.support.ClassPathXmlApplicationContext - -import akka.actor.Actor._ -import akka.actor.Props -import akka.actor.TypedActor -import akka.camel.CamelContextManager - /** - * @author Martin Krasser - */ -class Boot { + * Copyright (C) 2009-2010 Typesafe Inc. . + */ - // ----------------------------------------------------------------------- - // Basic example - // ----------------------------------------------------------------------- +// CAMEL IS NOT PART OF MILESTONE 1 OF AKKA 2.0 - actorOf[Consumer1] - actorOf[Consumer2] - - // ----------------------------------------------------------------------- - // Custom Camel route example - // ----------------------------------------------------------------------- - - // Create CamelContext and a Spring-based registry - val context = new ClassPathXmlApplicationContext("/context-jms.xml", getClass) - val registry = new ApplicationContextRegistry(context) - - // Use a custom Camel context and a custom touter builder - CamelContextManager.init(new DefaultCamelContext(registry)) - CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) - - val producer = actorOf[Producer1] - val mediator = actorOf(new Transformer(producer)) - val consumer = actorOf(new Consumer3(mediator)) - - // ----------------------------------------------------------------------- - // Asynchronous consumer-producer example (Akka homepage transformation) - // ----------------------------------------------------------------------- - - val httpTransformer = actorOf(new HttpTransformer) - val httpProducer = actorOf(new HttpProducer(httpTransformer)) - val httpConsumer = actorOf(new HttpConsumer(httpProducer)) - - // ----------------------------------------------------------------------- - // Publish subscribe examples - // ----------------------------------------------------------------------- - - // - // Cometd example commented out because camel-cometd is broken since Camel 2.3 - // - - //val cometdUri = "cometd://localhost:8111/test/abc?baseResource=file:target" - //val cometdSubscriber = actorOf(new Subscriber("cometd-subscriber", cometdUri)) - //val cometdPublisher = actorOf(new Publisher("cometd-publisher", cometdUri)) - - val jmsUri = "jms:topic:test" - val jmsSubscriber1 = actorOf(new Subscriber("jms-subscriber-1", jmsUri)) - val jmsSubscriber2 = actorOf(new Subscriber("jms-subscriber-2", jmsUri)) - val jmsPublisher = actorOf(new Publisher(jmsUri), "jms-publisher") - - //val cometdPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher)) - val jmsPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher)) - - // ----------------------------------------------------------------------- - // Actor un-publishing and re-publishing example - // ----------------------------------------------------------------------- - - actorOf[Consumer4] // POSTing "stop" to http://0.0.0.0:8877/camel/stop stops and unpublishes this actor - actorOf[Consumer5] // POSTing any msg to http://0.0.0.0:8877/camel/start starts and published Consumer4 again. - - // ----------------------------------------------------------------------- - // Active object example - // ----------------------------------------------------------------------- - - // TODO: investigate why this consumer is not published - TypedActor.typedActorOf(classOf[TypedConsumer1], classOf[TypedConsumer1Impl], Props()) -} - -/** - * @author Martin Krasser - */ -class CustomRouteBuilder extends RouteBuilder { - def configure { - val actorUri = "actor:%s" format classOf[Consumer2].getName - from("jetty:http://0.0.0.0:8877/camel/custom").to(actorUri) - from("direct:welcome").process(new Processor() { - def process(exchange: Exchange) { - exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody) - } - }) - } -} +//package sample.camel +// +//import org.apache.camel.{ Exchange, Processor } +//import org.apache.camel.builder.RouteBuilder +//import org.apache.camel.impl.DefaultCamelContext +//import org.apache.camel.spring.spi.ApplicationContextRegistry +//import org.springframework.context.support.ClassPathXmlApplicationContext +// +//import akka.actor.Actor._ +//import akka.actor.Props +//import akka.actor.TypedActor +//import akka.camel.CamelContextManager +// +///** +// * @author Martin Krasser +// */ +//class Boot { +// +// // ----------------------------------------------------------------------- +// // Basic example +// // ----------------------------------------------------------------------- +// +// actorOf[Consumer1] +// actorOf[Consumer2] +// +// // ----------------------------------------------------------------------- +// // Custom Camel route example +// // ----------------------------------------------------------------------- +// +// // Create CamelContext and a Spring-based registry +// val context = new ClassPathXmlApplicationContext("/context-jms.xml", getClass) +// val registry = new ApplicationContextRegistry(context) +// +// // Use a custom Camel context and a custom touter builder +// CamelContextManager.init(new DefaultCamelContext(registry)) +// CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) +// +// val producer = actorOf[Producer1] +// val mediator = actorOf(new Transformer(producer)) +// val consumer = actorOf(new Consumer3(mediator)) +// +// // ----------------------------------------------------------------------- +// // Asynchronous consumer-producer example (Akka homepage transformation) +// // ----------------------------------------------------------------------- +// +// val httpTransformer = actorOf(new HttpTransformer) +// val httpProducer = actorOf(new HttpProducer(httpTransformer)) +// val httpConsumer = actorOf(new HttpConsumer(httpProducer)) +// +// // ----------------------------------------------------------------------- +// // Publish subscribe examples +// // ----------------------------------------------------------------------- +// +// // +// // Cometd example commented out because camel-cometd is broken since Camel 2.3 +// // +// +// //val cometdUri = "cometd://localhost:8111/test/abc?baseResource=file:target" +// //val cometdSubscriber = actorOf(new Subscriber("cometd-subscriber", cometdUri)) +// //val cometdPublisher = actorOf(new Publisher("cometd-publisher", cometdUri)) +// +// val jmsUri = "jms:topic:test" +// val jmsSubscriber1 = actorOf(new Subscriber("jms-subscriber-1", jmsUri)) +// val jmsSubscriber2 = actorOf(new Subscriber("jms-subscriber-2", jmsUri)) +// val jmsPublisher = actorOf(new Publisher(jmsUri), "jms-publisher") +// +// //val cometdPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher)) +// val jmsPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher)) +// +// // ----------------------------------------------------------------------- +// // Actor un-publishing and re-publishing example +// // ----------------------------------------------------------------------- +// +// actorOf[Consumer4] // POSTing "stop" to http://0.0.0.0:8877/camel/stop stops and unpublishes this actor +// actorOf[Consumer5] // POSTing any msg to http://0.0.0.0:8877/camel/start starts and published Consumer4 again. +// +// // ----------------------------------------------------------------------- +// // Active object example +// // ----------------------------------------------------------------------- +// +// // TODO: investigate why this consumer is not published +// TypedActor.typedActorOf(classOf[TypedConsumer1], classOf[TypedConsumer1Impl], Props()) +//} +// +///** +// * @author Martin Krasser +// */ +//class CustomRouteBuilder extends RouteBuilder { +// def configure { +// val actorUri = "actor:%s" format classOf[Consumer2].getName +// from("jetty:http://0.0.0.0:8877/camel/custom").to(actorUri) +// from("direct:welcome").process(new Processor() { +// def process(exchange: Exchange) { +// exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody) +// } +// }) +// } +//} diff --git a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ClientApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ClientApplication.scala index c5662ea3b6..a4c5edf398 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ClientApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ClientApplication.scala @@ -1,29 +1,35 @@ -package sample.camel - -import akka.actor.Actor._ -import akka.actor.TypedActor -import akka.camel.Message - /** - * @author Martin Krasser - */ -object ClientApplication extends App { - - /* TODO: fix remote example - - val actor1 = remote.actorOf[RemoteActor1]("localhost", 7777) - val actor2 = remote.actorFor("remote2", "localhost", 7777) - - val typedActor1 = - TypedActor.newRemoteInstance(classOf[RemoteTypedConsumer1],classOf[RemoteTypedConsumer1Impl], "localhost", 7777) - - val typedActor2 = remote.typedActorFor(classOf[RemoteTypedConsumer2], "remote3", "localhost", 7777) - - println(actor1 !! Message("actor1")) // activates and publishes actor remotely - println(actor2 !! Message("actor2")) // actor already activated and published remotely - - println(typedActor1.foo("x1", "y1")) // activates and publishes typed actor methods remotely - println(typedActor2.foo("x2", "y2")) // typed actor methods already activated and published remotely - + * Copyright (C) 2009-2010 Typesafe Inc. . */ -} + +// CAMEL IS NOT PART OF MILESTONE 1 OF AKKA 2.0 + +//package sample.camel +// +//import akka.actor.Actor._ +//import akka.actor.TypedActor +//import akka.camel.Message +// +///** +// * @author Martin Krasser +// */ +//object ClientApplication extends App { +// +// /* TODO: fix remote example +// +// val actor1 = remote.actorOf[RemoteActor1]("localhost", 7777) +// val actor2 = remote.actorFor("remote2", "localhost", 7777) +// +// val typedActor1 = +// TypedActor.newRemoteInstance(classOf[RemoteTypedConsumer1],classOf[RemoteTypedConsumer1Impl], "localhost", 7777) +// +// val typedActor2 = remote.typedActorFor(classOf[RemoteTypedConsumer2], "remote3", "localhost", 7777) +// +// println(actor1 !! Message("actor1")) // activates and publishes actor remotely +// println(actor2 !! Message("actor2")) // actor already activated and published remotely +// +// println(typedActor1.foo("x1", "y1")) // activates and publishes typed actor methods remotely +// println(typedActor2.foo("x2", "y2")) // typed actor methods already activated and published remotely +// +// */ +//} diff --git a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ServerApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ServerApplication.scala index aae7a61d99..1181e661d4 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ServerApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/ServerApplication.scala @@ -1,27 +1,33 @@ -package sample.camel - -import akka.actor.Actor._ -import akka.camel.CamelServiceManager -import akka.actor.{ TypedActor, Props } - /** - * @author Martin Krasser - */ -object ServerApplication extends App { - import CamelServiceManager._ - - /* TODO: fix remote example - - startCamelService - - val ua = actorOf[RemoteActor2] - val ta = TypedActor.typedActorOf( - classOf[RemoteTypedConsumer2], - classOf[RemoteTypedConsumer2Impl], Props()) - - remote.start("localhost", 7777) - remote.register("remote2", ua) - remote.registerTypedActor("remote3", ta) - + * Copyright (C) 2009-2010 Typesafe Inc. . */ -} + +// CAMEL IS NOT PART OF MILESTONE 1 OF AKKA 2.0 + +//package sample.camel +// +//import akka.actor.Actor._ +//import akka.camel.CamelServiceManager +//import akka.actor.{ TypedActor, Props } +// +///** +// * @author Martin Krasser +// */ +//object ServerApplication extends App { +// import CamelServiceManager._ +// +// /* TODO: fix remote example +// +// startCamelService +// +// val ua = actorOf[RemoteActor2] +// val ta = TypedActor.typedActorOf( +// classOf[RemoteTypedConsumer2], +// classOf[RemoteTypedConsumer2Impl], Props()) +// +// remote.start("localhost", 7777) +// remote.register("remote2", ua) +// remote.registerTypedActor("remote3", ta) +// +// */ +//} diff --git a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/StandaloneApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/StandaloneApplication.scala index 62506c5c5a..c87e6bdcab 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/sample/camel/StandaloneApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/sample/camel/StandaloneApplication.scala @@ -1,128 +1,134 @@ -package sample.camel - -import org.apache.camel.impl.{ DefaultCamelContext, SimpleRegistry } -import org.apache.camel.builder.RouteBuilder -import org.apache.camel.spring.spi.ApplicationContextRegistry -import org.springframework.context.support.ClassPathXmlApplicationContext - -import akka.actor.{ Actor, TypedActor, Props } -import akka.camel._ - /** - * @author Martin Krasser - */ -object StandaloneApplication extends App { - import CamelContextManager._ - import CamelServiceManager._ + * Copyright (C) 2009-2010 Typesafe Inc. . + */ - // 'externally' register typed actors - val registry = new SimpleRegistry - registry.put("sample", TypedActor.typedActorOf(classOf[BeanIntf], classOf[BeanImpl], Props())) - - // customize CamelContext - CamelContextManager.init(new DefaultCamelContext(registry)) - CamelContextManager.mandatoryContext.addRoutes(new StandaloneApplicationRoute) - - startCamelService - - // access 'externally' registered typed actors - assert("hello msg1" == mandatoryContext.createProducerTemplate.requestBody("direct:test", "msg1")) - - mandatoryService.awaitEndpointActivation(1) { - // 'internally' register typed actor (requires CamelService) - TypedActor.typedActorOf(classOf[TypedConsumer2], classOf[TypedConsumer2Impl], Props()) - } - - // access 'internally' (automatically) registered typed-actors - // (see @consume annotation value at TypedConsumer2.foo method) - assert("default: msg3" == mandatoryContext.createProducerTemplate.requestBody("direct:default", "msg3")) - - stopCamelService - - Actor.registry.local.shutdownAll -} - -class StandaloneApplicationRoute extends RouteBuilder { - def configure = { - // route to typed actors (in SimpleRegistry) - from("direct:test").to("typed-actor:sample?method=foo") - } -} - -object StandaloneSpringApplication extends App { - import CamelContextManager._ - - // load Spring application context - val appctx = new ClassPathXmlApplicationContext("/context-standalone.xml") - - // We cannot use the CamelServiceManager to wait for endpoint activation - // because CamelServiceManager is started by the Spring application context. - // (and hence is not available for setting expectations on activations). This - // will be improved/enabled in upcoming releases. - Thread.sleep(1000) - - // access 'externally' registered typed actors with typed-actor component - assert("hello msg3" == mandatoryTemplate.requestBody("direct:test3", "msg3")) - - // access auto-started untyped consumer - assert("received msg3" == mandatoryTemplate.requestBody("direct:untyped-consumer-1", "msg3")) - - appctx.close - - Actor.registry.local.shutdownAll -} - -class StandaloneSpringApplicationRoute extends RouteBuilder { - def configure = { - // routes to typed actor (in ApplicationContextRegistry) - from("direct:test3").to("typed-actor:ta?method=foo") - } -} - -object StandaloneJmsApplication extends App { - import CamelServiceManager._ - - val context = new ClassPathXmlApplicationContext("/context-jms.xml") - val registry = new ApplicationContextRegistry(context) - - // Init CamelContextManager with custom CamelContext - CamelContextManager.init(new DefaultCamelContext(registry)) - - startCamelService - - val jmsUri = "jms:topic:test" - val jmsPublisher = Actor.actorOf(new Publisher(jmsUri), "jms-publisher") - - mandatoryService.awaitEndpointActivation(2) { - Actor.actorOf(new Subscriber("jms-subscriber-1", jmsUri)) - Actor.actorOf(new Subscriber("jms-subscriber-2", jmsUri)) - } - - // Send 10 messages to via publisher actor - for (i ← 1 to 10) { - jmsPublisher ! ("Akka rocks (%d)" format i) - } - - // Send 10 messages to JMS topic directly - for (i ← 1 to 10) { - CamelContextManager.mandatoryTemplate.sendBody(jmsUri, "Camel rocks (%d)" format i) - } - - // Wait a bit for subscribes to receive messages - Thread.sleep(1000) - - stopCamelService - Actor.registry.local.shutdownAll -} - -object StandaloneFileApplication { - import CamelServiceManager._ - - def main(args: Array[String]) { - startCamelService - mandatoryService.awaitEndpointActivation(1) { - Actor.actorOf(new FileConsumer) - } - } -} +// CAMEL IS NOT PART OF MILESTONE 1 OF AKKA 2.0 +//package sample.camel +// +//import org.apache.camel.impl.{ DefaultCamelContext, SimpleRegistry } +//import org.apache.camel.builder.RouteBuilder +//import org.apache.camel.spring.spi.ApplicationContextRegistry +//import org.springframework.context.support.ClassPathXmlApplicationContext +// +//import akka.actor.{ Actor, TypedActor, Props } +//import akka.camel._ +// +///** +// * @author Martin Krasser +// */ +//object StandaloneApplication extends App { +// import CamelContextManager._ +// import CamelServiceManager._ +// +// // 'externally' register typed actors +// val registry = new SimpleRegistry +// registry.put("sample", TypedActor.typedActorOf(classOf[BeanIntf], classOf[BeanImpl], Props())) +// +// // customize CamelContext +// CamelContextManager.init(new DefaultCamelContext(registry)) +// CamelContextManager.mandatoryContext.addRoutes(new StandaloneApplicationRoute) +// +// startCamelService +// +// // access 'externally' registered typed actors +// assert("hello msg1" == mandatoryContext.createProducerTemplate.requestBody("direct:test", "msg1")) +// +// mandatoryService.awaitEndpointActivation(1) { +// // 'internally' register typed actor (requires CamelService) +// TypedActor.typedActorOf(classOf[TypedConsumer2], classOf[TypedConsumer2Impl], Props()) +// } +// +// // access 'internally' (automatically) registered typed-actors +// // (see @consume annotation value at TypedConsumer2.foo method) +// assert("default: msg3" == mandatoryContext.createProducerTemplate.requestBody("direct:default", "msg3")) +// +// stopCamelService +// +// Actor.registry.local.shutdownAll +//} +// +//class StandaloneApplicationRoute extends RouteBuilder { +// def configure = { +// // route to typed actors (in SimpleRegistry) +// from("direct:test").to("typed-actor:sample?method=foo") +// } +//} +// +//object StandaloneSpringApplication extends App { +// import CamelContextManager._ +// +// // load Spring application context +// val appctx = new ClassPathXmlApplicationContext("/context-standalone.xml") +// +// // We cannot use the CamelServiceManager to wait for endpoint activation +// // because CamelServiceManager is started by the Spring application context. +// // (and hence is not available for setting expectations on activations). This +// // will be improved/enabled in upcoming releases. +// Thread.sleep(1000) +// +// // access 'externally' registered typed actors with typed-actor component +// assert("hello msg3" == mandatoryTemplate.requestBody("direct:test3", "msg3")) +// +// // access auto-started untyped consumer +// assert("received msg3" == mandatoryTemplate.requestBody("direct:untyped-consumer-1", "msg3")) +// +// appctx.close +// +// Actor.registry.local.shutdownAll +//} +// +//class StandaloneSpringApplicationRoute extends RouteBuilder { +// def configure = { +// // routes to typed actor (in ApplicationContextRegistry) +// from("direct:test3").to("typed-actor:ta?method=foo") +// } +//} +// +//object StandaloneJmsApplication extends App { +// import CamelServiceManager._ +// +// val context = new ClassPathXmlApplicationContext("/context-jms.xml") +// val registry = new ApplicationContextRegistry(context) +// +// // Init CamelContextManager with custom CamelContext +// CamelContextManager.init(new DefaultCamelContext(registry)) +// +// startCamelService +// +// val jmsUri = "jms:topic:test" +// val jmsPublisher = Actor.actorOf(new Publisher(jmsUri), "jms-publisher") +// +// mandatoryService.awaitEndpointActivation(2) { +// Actor.actorOf(new Subscriber("jms-subscriber-1", jmsUri)) +// Actor.actorOf(new Subscriber("jms-subscriber-2", jmsUri)) +// } +// +// // Send 10 messages to via publisher actor +// for (i ← 1 to 10) { +// jmsPublisher ! ("Akka rocks (%d)" format i) +// } +// +// // Send 10 messages to JMS topic directly +// for (i ← 1 to 10) { +// CamelContextManager.mandatoryTemplate.sendBody(jmsUri, "Camel rocks (%d)" format i) +// } +// +// // Wait a bit for subscribes to receive messages +// Thread.sleep(1000) +// +// stopCamelService +// Actor.registry.local.shutdownAll +//} +// +//object StandaloneFileApplication { +// import CamelServiceManager._ +// +// def main(args: Array[String]) { +// startCamelService +// mandatoryService.awaitEndpointActivation(1) { +// Actor.actorOf(new FileConsumer) +// } +// } +//} +// diff --git a/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala b/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala index d9b58ef771..49b5da2138 100644 --- a/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala +++ b/akka-samples/akka-sample-chat/src/main/scala/ChatServer.scala @@ -1,253 +1,256 @@ - /** - * Copyright (C) 2009-2010 Typesafe Inc. . - */ +/** + * Copyright (C) 2009-2010 Typesafe Inc. . + */ - package sample.chat - - import scala.collection.mutable.HashMap - - import akka.actor.{Actor, ActorRef, Props} - import akka.stm._ - import akka.actor.Actor._ - import akka.event.EventHandler - - /****************************************************************************** - Akka Chat Client/Server Sample Application - - How to run the sample: - - 1. Fire up two shells. For each of them: - - Step down into to the root of the Akka distribution. - - Set 'export AKKA_HOME=. - - Run 'sbt console' to start up a REPL (interpreter). - 2. In the first REPL you get execute: - - scala> import sample.chat._ - - scala> import akka.actor.Actor._ - - scala> val chatService = actorOf[ChatService] - 3. In the second REPL you get execute: - - scala> import sample.chat._ - - scala> ClientRunner.run - 4. See the chat simulation run. - 5. Run it again to see full speed after first initialization. - 6. In the client REPL, or in a new REPL, you can also create your own client - - scala> import sample.chat._ - - scala> val myClient = new ChatClient("") - - scala> myClient.login - - scala> myClient.post("Can I join?") - - scala> println("CHAT LOG:\n\t" + myClient.chatLog.log.mkString("\n\t")) - - - That’s it. Have fun. - - ******************************************************************************/ - - /** - * ChatServer's internal events. - */ - sealed trait Event - case class Login(user: String) extends Event - case class Logout(user: String) extends Event - case class GetChatLog(from: String) extends Event - case class ChatLog(log: List[String]) extends Event - case class ChatMessage(from: String, message: String) extends Event - - /** - * Chat client. - */ - class ChatClient(val name: String) { - val chat = Actor.remote.actorFor("chat:service", "localhost", 2552) - - def login = chat ! Login(name) - def logout = chat ! Logout(name) - def post(message: String) = chat ! ChatMessage(name, name + ": " + message) - def chatLog = (chat !! GetChatLog(name)).as[ChatLog].getOrElse(throw new Exception("Couldn't get the chat log from ChatServer")) - } - - /** - * Internal chat client session. - */ - class Session(user: String, storage: ActorRef) extends Actor { - private val loginTime = System.currentTimeMillis - private var userLog: List[String] = Nil - - EventHandler.info(this, "New session for user [%s] has been created at [%s]".format(user, loginTime)) - - def receive = { - case msg @ ChatMessage(from, message) => - userLog ::= message - storage ! msg - - case msg @ GetChatLog(_) => - storage forward msg - } - } - - /** - * Abstraction of chat storage holding the chat log. - */ - trait ChatStorage extends Actor - - /** - * Memory-backed chat storage implementation. - */ - class MemoryChatStorage extends ChatStorage { - private var chatLog = TransactionalVector[Array[Byte]]() - - EventHandler.info(this, "Memory-based chat storage is starting up...") - - def receive = { - case msg @ ChatMessage(from, message) => - EventHandler.debug(this, "New chat message [%s]".format(message)) - atomic { chatLog + message.getBytes("UTF-8") } - - case GetChatLog(_) => - val messageList = atomic { chatLog.map(bytes => new String(bytes, "UTF-8")).toList } - reply(ChatLog(messageList)) - } - - override def postRestart(reason: Throwable) { - chatLog = TransactionalVector() - } - } - - /** - * Implements user session management. - *

- * Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor. - */ - trait SessionManagement { this: Actor => - - val storage: ActorRef // needs someone to provide the ChatStorage - val sessions = new HashMap[String, ActorRef] - - protected def sessionManagement: Receive = { - case Login(username) => - EventHandler.info(this, "User [%s] has logged in".format(username)) - val session = actorOf(new Session(username, storage)) - session - sessions += (username -> session) - - case Logout(username) => - EventHandler.info(this, "User [%s] has logged out".format(username)) - val session = sessions(username) - session.stop() - sessions -= username - } - - protected def shutdownSessions() { - sessions.foreach { case (_, session) => session.stop() } - } - } - - /** - * Implements chat management, e.g. chat message dispatch. - *

- * Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor. - */ - trait ChatManagement { this: Actor => - val sessions: HashMap[String, ActorRef] // needs someone to provide the Session map - - protected def chatManagement: Receive = { - case msg @ ChatMessage(from, _) => getSession(from).foreach(_ ! msg) - case msg @ GetChatLog(from) => getSession(from).foreach(_ forward msg) - } - - private def getSession(from: String) : Option[ActorRef] = { - if (sessions.contains(from)) - Some(sessions(from)) - else { - EventHandler.info(this, "Session expired for %s".format(from)) - None - } - } - } - - /** - * Creates and links a MemoryChatStorage. - */ - trait MemoryChatStorageFactory { this: Actor => - val storage = actorOf(Props[MemoryChatStorage].withSupervisor(this.self)) // starts and links ChatStorage - } - - /** - * Chat server. Manages sessions and redirects all other messages to the Session for the client. - */ - trait ChatServer extends Actor { - //faultHandler = OneForOneStrategy(List(classOf[Exception]),5, 5000) - val storage: ActorRef - - EventHandler.info(this, "Chat server is starting up...") - - // actor message handler - def receive: Receive = sessionManagement orElse chatManagement - - // abstract methods to be defined somewhere else - protected def chatManagement: Receive - protected def sessionManagement: Receive - protected def shutdownSessions() - - override def postStop() { - EventHandler.info(this, "Chat server is shutting down...") - shutdownSessions() - storage.stop() - } - } - - /** - * Class encapsulating the full Chat Service. - * Start service by invoking: - *

-   * val chatService = Actor.actorOf[ChatService]
-   * 
- */ - class ChatService extends - ChatServer with - SessionManagement with - ChatManagement with - MemoryChatStorageFactory { - override def preStart() { - remote.start("localhost", 2552); - remote.register("chat:service", self) //Register the actor with the specified service id - } - } - - /** - * Test runner starting ChatService. - */ - object ServerRunner { - - def main(args: Array[String]) { ServerRunner.run() } - - def run() { - actorOf[ChatService] - } - } - - /** - * Test runner emulating a chat session. - */ - object ClientRunner { - - def main(args: Array[String]) { ClientRunner.run() } - - def run() { - - val client1 = new ChatClient("jonas") - client1.login - val client2 = new ChatClient("patrik") - client2.login - - client1.post("Hi there") - println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t")) - - client2.post("Hello") - println("CHAT LOG:\n\t" + client2.chatLog.log.mkString("\n\t")) - - client1.post("Hi again") - println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t")) - - client1.logout - client2.logout - } - } +// REMOTING IS NOT PART OF MILESTONE 1 OF AKKA 2.0 +// +// package sample.chat +// +// import scala.collection.mutable.HashMap +// +// import akka.actor.{Actor, ActorRef, Props} +// import akka.stm._ +// import akka.actor.Actor._ +// import akka.event.EventHandler +// +// /****************************************************************************** +// Akka Chat Client/Server Sample Application +// +// How to run the sample: +// +// 1. Fire up two shells. For each of them: +// - Step down into to the root of the Akka distribution. +// - Set 'export AKKA_HOME=. +// - Run 'sbt console' to start up a REPL (interpreter). +// 2. In the first REPL you get execute: +// - scala> import sample.chat._ +// - scala> import akka.actor.Actor._ +// - scala> val chatService = actorOf[ChatService] +// 3. In the second REPL you get execute: +// - scala> import sample.chat._ +// - scala> ClientRunner.run +// 4. See the chat simulation run. +// 5. Run it again to see full speed after first initialization. +// 6. In the client REPL, or in a new REPL, you can also create your own client +// - scala> import sample.chat._ +// - scala> val myClient = new ChatClient("") +// - scala> myClient.login +// - scala> myClient.post("Can I join?") +// - scala> println("CHAT LOG:\n\t" + myClient.chatLog.log.mkString("\n\t")) +// +// +// That’s it. Have fun. +// +// ******************************************************************************/ +// +// /** +// * ChatServer's internal events. +// */ +// sealed trait Event +// case class Login(user: String) extends Event +// case class Logout(user: String) extends Event +// case class GetChatLog(from: String) extends Event +// case class ChatLog(log: List[String]) extends Event +// case class ChatMessage(from: String, message: String) extends Event +// +// /** +// * Chat client. +// */ +// class ChatClient(val name: String) { +// val chat = Actor.remote.actorFor("chat:service", "localhost", 2552) +// +// def login = chat ! Login(name) +// def logout = chat ! Logout(name) +// def post(message: String) = chat ! ChatMessage(name, name + ": " + message) +// def chatLog = (chat !! GetChatLog(name)).as[ChatLog].getOrElse(throw new Exception("Couldn't get the chat log from ChatServer")) +// } +// +// /** +// * Internal chat client session. +// */ +// class Session(user: String, storage: ActorRef) extends Actor { +// private val loginTime = System.currentTimeMillis +// private var userLog: List[String] = Nil +// +// EventHandler.info(this, "New session for user [%s] has been created at [%s]".format(user, loginTime)) +// +// def receive = { +// case msg @ ChatMessage(from, message) => +// userLog ::= message +// storage ! msg +// +// case msg @ GetChatLog(_) => +// storage forward msg +// } +// } +// +// /** +// * Abstraction of chat storage holding the chat log. +// */ +// trait ChatStorage extends Actor +// +// /** +// * Memory-backed chat storage implementation. +// */ +// class MemoryChatStorage extends ChatStorage { +// private var chatLog = TransactionalVector[Array[Byte]]() +// +// EventHandler.info(this, "Memory-based chat storage is starting up...") +// +// def receive = { +// case msg @ ChatMessage(from, message) => +// EventHandler.debug(this, "New chat message [%s]".format(message)) +// atomic { chatLog + message.getBytes("UTF-8") } +// +// case GetChatLog(_) => +// val messageList = atomic { chatLog.map(bytes => new String(bytes, "UTF-8")).toList } +// reply(ChatLog(messageList)) +// } +// +// override def postRestart(reason: Throwable) { +// chatLog = TransactionalVector() +// } +// } +// +// /** +// * Implements user session management. +// *

+// * Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor. +// */ +// trait SessionManagement { this: Actor => +// +// val storage: ActorRef // needs someone to provide the ChatStorage +// val sessions = new HashMap[String, ActorRef] +// +// protected def sessionManagement: Receive = { +// case Login(username) => +// EventHandler.info(this, "User [%s] has logged in".format(username)) +// val session = actorOf(new Session(username, storage)) +// session +// sessions += (username -> session) +// +// case Logout(username) => +// EventHandler.info(this, "User [%s] has logged out".format(username)) +// val session = sessions(username) +// session.stop() +// sessions -= username +// } +// +// protected def shutdownSessions() { +// sessions.foreach { case (_, session) => session.stop() } +// } +// } +// +// /** +// * Implements chat management, e.g. chat message dispatch. +// *

+// * Uses self-type annotation (this: Actor =>) to declare that it needs to be mixed in with an Actor. +// */ +// trait ChatManagement { this: Actor => +// val sessions: HashMap[String, ActorRef] // needs someone to provide the Session map +// +// protected def chatManagement: Receive = { +// case msg @ ChatMessage(from, _) => getSession(from).foreach(_ ! msg) +// case msg @ GetChatLog(from) => getSession(from).foreach(_ forward msg) +// } +// +// private def getSession(from: String) : Option[ActorRef] = { +// if (sessions.contains(from)) +// Some(sessions(from)) +// else { +// EventHandler.info(this, "Session expired for %s".format(from)) +// None +// } +// } +// } +// +// /** +// * Creates and links a MemoryChatStorage. +// */ +// trait MemoryChatStorageFactory { this: Actor => +// val storage = actorOf(Props[MemoryChatStorage].withSupervisor(this.self)) // starts and links ChatStorage +// } +// +// /** +// * Chat server. Manages sessions and redirects all other messages to the Session for the client. +// */ +// trait ChatServer extends Actor { +// //faultHandler = OneForOneStrategy(List(classOf[Exception]),5, 5000) +// val storage: ActorRef +// +// EventHandler.info(this, "Chat server is starting up...") +// +// // actor message handler +// def receive: Receive = sessionManagement orElse chatManagement +// +// // abstract methods to be defined somewhere else +// protected def chatManagement: Receive +// protected def sessionManagement: Receive +// protected def shutdownSessions() +// +// override def postStop() { +// EventHandler.info(this, "Chat server is shutting down...") +// shutdownSessions() +// storage.stop() +// } +// } +// +// /** +// * Class encapsulating the full Chat Service. +// * Start service by invoking: +// *

+//   * val chatService = Actor.actorOf[ChatService]
+//   * 
+// */ +// class ChatService extends +// ChatServer with +// SessionManagement with +// ChatManagement with +// MemoryChatStorageFactory { +// override def preStart() { +// remote.start("localhost", 2552); +// remote.register("chat:service", self) //Register the actor with the specified service id +// } +// } +// +// /** +// * Test runner starting ChatService. +// */ +// object ServerRunner { +// +// def main(args: Array[String]) { ServerRunner.run() } +// +// def run() { +// actorOf[ChatService] +// } +// } +// +// /** +// * Test runner emulating a chat session. +// */ +// object ClientRunner { +// +// def main(args: Array[String]) { ClientRunner.run() } +// +// def run() { +// +// val client1 = new ChatClient("jonas") +// client1.login +// val client2 = new ChatClient("patrik") +// client2.login +// +// client1.post("Hi there") +// println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t")) +// +// client2.post("Hello") +// println("CHAT LOG:\n\t" + client2.chatLog.log.mkString("\n\t")) +// +// client1.post("Hi again") +// println("CHAT LOG:\n\t" + client1.chatLog.log.mkString("\n\t")) +// +// client1.logout +// client2.logout +// } +// } +// diff --git a/akka-samples/akka-sample-fsm/src/README b/akka-samples/akka-sample-fsm/src/README new file mode 100644 index 0000000000..17971c005b --- /dev/null +++ b/akka-samples/akka-sample-fsm/src/README @@ -0,0 +1,30 @@ +FSM +=== + +Requirements +------------ + +To build and run FSM you need [Simple Build Tool][sbt] (sbt). + +Running +------- + +First time, 'sbt update' to get dependencies, then to run Ants use 'sbt run'. +Here is an example. First type 'sbt' to start SBT interactively, the run 'update' and 'run': +> cd $AKKA_HOME + +> % sbt + +> > update + +> > project akka-sample-fsm + +> > run + +> > Choose 1 or 2 depending on what sample you wish to run + +Notice +------ + +[akka]: http://akka.io +[sbt]: http://code.google.com/p/simple-build-tool/ diff --git a/akka-samples/akka-sample-fsm/src/main/scala/Buncher.scala b/akka-samples/akka-sample-fsm/src/main/scala/Buncher.scala index 0dcf33e401..d039609a98 100644 --- a/akka-samples/akka-sample-fsm/src/main/scala/Buncher.scala +++ b/akka-samples/akka-sample-fsm/src/main/scala/Buncher.scala @@ -1,3 +1,6 @@ +/** + * Copyright (C) 2009-2010 Typesafe Inc. . + */ package sample.fsm.buncher import akka.actor.ActorRefFactory @@ -6,15 +9,15 @@ import akka.util.Duration import akka.actor.{ FSM, Actor, ActorRef } /* - * generic typed object buncher. - * - * To instantiate it, use the factory method like so: - * Buncher(100, 500)(x : List[AnyRef] => x foreach println) - * which will yield a fully functional ActorRef. - * The type of messages allowed is strongly typed to match the - * supplied processing method; other messages are discarded (and - * possibly logged). - */ +* generic typed object buncher. +* +* To instantiate it, use the factory method like so: +* Buncher(100, 500)(x : List[AnyRef] => x foreach println) +* which will yield a fully functional ActorRef. +* The type of messages allowed is strongly typed to match the +* supplied processing method; other messages are discarded (and +* possibly logged). +*/ object GenericBuncher { trait State case object Idle extends State diff --git a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala index 2c23940c9f..3acbf473e6 100644 --- a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala +++ b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala @@ -1,3 +1,6 @@ +/** + * Copyright (C) 2009-2010 Typesafe Inc. . + */ package sample.fsm.dining.become //Akka adaptation of @@ -7,8 +10,8 @@ import akka.actor.{ ActorRef, Actor, ActorSystem } import akka.util.duration._ /* - * First we define our messages, they basically speak for themselves - */ +* First we define our messages, they basically speak for themselves +*/ sealed trait DiningHakkerMessage case class Busy(chopstick: ActorRef) extends DiningHakkerMessage case class Put(hakker: ActorRef) extends DiningHakkerMessage @@ -18,9 +21,9 @@ object Eat extends DiningHakkerMessage object Think extends DiningHakkerMessage /* - * A Chopstick is an actor, it can be taken, and put back - */ -class Chopstick(name: String) extends Actor { +* A Chopstick is an actor, it can be taken, and put back +*/ +class Chopstick extends Actor { //When a Chopstick is taken by a hakker //It will refuse to be taken by other hakkers @@ -44,8 +47,8 @@ class Chopstick(name: String) extends Actor { } /* - * A hakker is an awesome dude or dudett who either thinks about hacking or has to eat ;-) - */ +* 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 { //When a hakker is thinking it can become hungry @@ -75,7 +78,7 @@ class Hakker(name: String, left: ActorRef, right: ActorRef) extends Actor { //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", name, left.address, right.address) + println("%s has picked up %s and %s and starts to eat".format(name, left.name, right.name)) become(eating) system.scheduler.scheduleOnce(self, Think, 5 seconds) @@ -105,27 +108,33 @@ class Hakker(name: String, left: ActorRef, right: ActorRef) extends Actor { become(thinking) left ! Put(self) right ! Put(self) - println("%s puts down his chopsticks and starts to think", name) + println("%s puts down his chopsticks and starts to think".format(name)) system.scheduler.scheduleOnce(self, Eat, 5 seconds) } //All hakkers start in a non-eating state def receive = { case Think ⇒ - println("%s starts to think", name) + println("%s starts to think".format(name)) become(thinking) system.scheduler.scheduleOnce(self, Eat, 5 seconds) } } /* - * Alright, here's our test-harness - */ +* Alright, here's our test-harness +*/ object DiningHakkers { val system = ActorSystem() + + def main(args: Array[String]) { + run + } + def run { //Create 5 chopsticks - val chopsticks = for (i ← 1 to 5) yield system.actorOf(new Chopstick("Chopstick " + i)) + val chopsticks = for (i ← 1 to 5) yield system.actorOf[Chopstick]("Chopstick " + i) + //Create 5 awesome hakkers and assign them their left and right chopstick val hakkers = for { (name, i) ← List("Ghosh", "Bonér", "Klang", "Krasser", "Manie").zipWithIndex diff --git a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala index 987f630784..d0c8bca54a 100644 --- a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala +++ b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala @@ -1,3 +1,6 @@ +/** + * Copyright (C) 2009-2010 Typesafe Inc. . + */ package sample.fsm.dining.fsm import akka.actor.{ ActorRef, Actor, FSM, ActorSystem } @@ -6,8 +9,8 @@ import akka.util.Duration import akka.util.duration._ /* - * Some messages for the chopstick - */ +* Some messages for the chopstick +*/ sealed trait ChopstickMessage object Take extends ChopstickMessage object Put extends ChopstickMessage @@ -27,9 +30,9 @@ case object Taken extends ChopstickState case class TakenBy(hakker: ActorRef) /* - * A chopstick is an actor, it can be taken, and put back - */ -class Chopstick(name: String) extends Actor with FSM[ChopstickState, TakenBy] { +* A chopstick is an actor, it can be taken, and put back +*/ +class Chopstick extends Actor with FSM[ChopstickState, TakenBy] { // A chopstick begins its existence as available and taken by no one startWith(Available, TakenBy(system.deadLetters)) @@ -77,8 +80,8 @@ case object Eating extends FSMHakkerState case class TakenChopsticks(left: Option[ActorRef], right: Option[ActorRef]) /* - * A fsm hakker is an awesome dude or dudette who either thinks about hacking or has to eat ;-) - */ +* A fsm hakker is an awesome dude or dudette who either thinks about hacking or has to eat ;-) +*/ class FSMHakker(name: String, left: ActorRef, right: ActorRef) extends Actor with FSM[FSMHakkerState, TakenChopsticks] { //All hakkers start waiting @@ -86,7 +89,7 @@ class FSMHakker(name: String, left: ActorRef, right: ActorRef) extends Actor wit when(Waiting) { case Event(Think, _) ⇒ - println("%s starts to think", name) + println("%s starts to think".format(name)) startThinking(5 seconds) } @@ -125,7 +128,7 @@ class FSMHakker(name: String, left: ActorRef, right: ActorRef) extends Actor wit } private def startEating(left: ActorRef, right: ActorRef): State = { - println("%s has picked up %s and %s, and starts to eat", name, left.address, right.address) + println("%s has picked up %s and %s and starts to eat".format(name, left.name, right.name)) goto(Eating) using TakenChopsticks(Some(left), Some(right)) forMax (5 seconds) } @@ -144,7 +147,7 @@ class FSMHakker(name: String, left: ActorRef, right: ActorRef) extends Actor wit // then he puts down his chopsticks and starts to think when(Eating) { case Event(StateTimeout, _) ⇒ - println("%s puts down his chopsticks and starts to think", name) + println("%s puts down his chopsticks and starts to think".format(name)) left ! Put right ! Put startThinking(5 seconds) @@ -159,15 +162,19 @@ class FSMHakker(name: String, left: ActorRef, right: ActorRef) extends Actor wit } /* - * Alright, here's our test-harness - */ +* Alright, here's our test-harness +*/ object DiningHakkersOnFsm { val system = ActorSystem() + def main(args: Array[String]) { + run + } + def run = { // Create 5 chopsticks - val chopsticks = for (i ← 1 to 5) yield system.actorOf(new Chopstick("Chopstick " + i)) + val chopsticks = for (i ← 1 to 5) yield system.actorOf[Chopstick]("Chopstick " + i) // Create 5 awesome fsm hakkers and assign them their left and right chopstick val hakkers = for { (name, i) ← List("Ghosh", "Bonér", "Klang", "Krasser", "Manie").zipWithIndex diff --git a/akka-samples/akka-sample-hello/config/akka.conf b/akka-samples/akka-sample-hello/config/akka.conf deleted file mode 100644 index 5b8920874f..0000000000 --- a/akka-samples/akka-sample-hello/config/akka.conf +++ /dev/null @@ -1,27 +0,0 @@ -#################### -# Akka Config File # -#################### - -akka { - version = "2.0-SNAPSHOT" - - enabled-modules = ["http"] - - time-unit = "seconds" - - event-handlers = ["akka.event.EventHandler$DefaultListener"] - - boot = ["sample.hello.Boot"] - - http { - hostname = "localhost" - port = 9998 - - connection-close = true - root-actor-id = "_httproot" - root-actor-builtin = true - timeout = 1000 - expired-header-name = "Async-Timeout" - expired-header-value = "expired" - } -} diff --git a/akka-samples/akka-sample-hello/config/microkernel-server.xml b/akka-samples/akka-sample-hello/config/microkernel-server.xml deleted file mode 100644 index 4f86dab23c..0000000000 --- a/akka-samples/akka-sample-hello/config/microkernel-server.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - 300000 - 2 - false - 8443 - 20000 - 5000 - - - - - - - - - - - - - - / - - akka.http.AkkaMistServlet - /* - - - - - - - - - - - - - - - true - true - true - 1000 - - diff --git a/akka-samples/akka-sample-hello/src/README b/akka-samples/akka-sample-hello/src/README new file mode 100644 index 0000000000..cd271f1dde --- /dev/null +++ b/akka-samples/akka-sample-hello/src/README @@ -0,0 +1,28 @@ +HELLO +===== + +Requirements +------------ + +To build and run FSM you need [Simple Build Tool][sbt] (sbt). + +Running +------- + +First time, 'sbt update' to get dependencies, then to run Ants use 'sbt run'. +Here is an example. First type 'sbt' to start SBT interactively, the run 'update' and 'run': +> cd $AKKA_HOME + +> % sbt + +> > update + +> > project akka-sample-hello + +> > run + +Notice +------ + +[akka]: http://akka.io +[sbt]: http://code.google.com/p/simple-build-tool/ diff --git a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Boot.scala b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Boot.scala deleted file mode 100644 index 149c6a3ee4..0000000000 --- a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Boot.scala +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (C) 2009-2011 Typesafe Inc. - */ - -package sample.hello - -import akka.actor._ -import akka.http._ - -class Boot { - val supervisor = Supervisor(OneForOneStrategy(List(classOf[Exception]), 3, 100)) - Actor.actorOf(Props[RootEndpoint].withSupervisor(supervisor)) - Actor.actorOf(Props[HelloEndpoint].withSupervisor(supervisor)) -} diff --git a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/HelloEndpoint.scala b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/HelloEndpoint.scala deleted file mode 100644 index 2ea8c1fe83..0000000000 --- a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/HelloEndpoint.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2009-2011 Typesafe Inc. - */ - -package sample.hello - -import akka.actor._ -import akka.http._ - -import java.text.DateFormat -import java.util.Date - -class HelloEndpoint extends Actor with Endpoint { - self.dispatcher = Endpoint.Dispatcher - - lazy val hello = Actor.actorOf( - new Actor { - def time = DateFormat.getTimeInstance.format(new Date) - def receive = { - case get: Get => get OK "Hello at " + time - } - }) - - def hook: Endpoint.Hook = { case _ => hello } - - override def preStart = Actor.registry.actorFor(MistSettings.RootActorID).get ! Endpoint.Attach(hook) - - def receive = handleHttpRequest -} diff --git a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala new file mode 100644 index 0000000000..e3399e86fc --- /dev/null +++ b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package sample.hello + +import akka.actor.{ ActorSystem, Actor } + +case object Start + +object Main { + def main(args: Array[String]) { + val system = ActorSystem() + system.actorOf[HelloActor] ! Start + } +} + +class HelloActor extends Actor { + val worldActor = system.actorOf[WorldActor] + def receive = { + case Start ⇒ worldActor ! "Hello" + case s: String ⇒ + println("Received message: %s".format(s)) + system.stop() + } +} + +class WorldActor extends Actor { + def receive = { + case s: String ⇒ sender ! s.toUpperCase + " world!" + } +} + diff --git a/akka-samples/akka-sample-osgi/src/main/scala/OsgiExample.scala b/akka-samples/akka-sample-osgi/src/main/scala/OsgiExample.scala index 3e2d7af049..bf257ffd49 100644 --- a/akka-samples/akka-sample-osgi/src/main/scala/OsgiExample.scala +++ b/akka-samples/akka-sample-osgi/src/main/scala/OsgiExample.scala @@ -3,29 +3,27 @@ */ package sample.osgi -import akka.actor.Actor -import akka.actor.Actor._ - import org.osgi.framework.{ BundleActivator, BundleContext } +import akka.actor.{ Timeout, ActorSystem, Actor } class Activator extends BundleActivator { + val system = ActorSystem() def start(context: BundleContext) { println("Starting the OSGi example ...") - val echo = actorOf[EchoActor] - val answer = (echo ? "OSGi example").as[String] + val echo = system.actorOf[EchoActor] + val answer = (echo ? ("OSGi example", Timeout(100))).as[String] println(answer getOrElse "No answer!") } def stop(context: BundleContext) { - Actor.registry.local.shutdownAll() + system.stop() println("Stopped the OSGi example.") } } class EchoActor extends Actor { - override def receive = { - case x => reply(x) + case x ⇒ sender ! x } } diff --git a/akka-samples/akka-sample-remote/src/main/scala/ServerManagedRemoteActorSample.scala b/akka-samples/akka-sample-remote/src/main/scala/ServerManagedRemoteActorSample.scala index 84a201f530..9b3a27a7ae 100644 --- a/akka-samples/akka-sample-remote/src/main/scala/ServerManagedRemoteActorSample.scala +++ b/akka-samples/akka-sample-remote/src/main/scala/ServerManagedRemoteActorSample.scala @@ -2,35 +2,37 @@ * Copyright (C) 2009-2011 Typesafe Inc. */ -package sample.remote - -import akka.actor.Actor._ -import akka.actor. {ActorRegistry, Actor} - -class HelloWorldActor extends Actor { - def receive = { - case "Hello" => - reply("World") - } -} - -object ServerManagedRemoteActorServer { - - def run = { - Actor.remote.start("localhost", 2552) - Actor.remote.register("hello-service", actorOf[HelloWorldActor]) - } - - def main(args: Array[String]) = run -} - -object ServerManagedRemoteActorClient { - - def run = { - val actor = Actor.remote.actorFor("hello-service", "localhost", 2552) - val result = actor !! "Hello" - } - - def main(args: Array[String]) = run -} +// REMOTING IS NOT PART OF MILESTONE 1 OF AKKA 2.0 +//package sample.remote +// +//import akka.actor.Actor._ +//import akka.actor. {ActorRegistry, Actor} +// +//class HelloWorldActor extends Actor { +// def receive = { +// case "Hello" => +// reply("World") +// } +//} +// +//object ServerManagedRemoteActorServer { +// +// def run = { +// Actor.remote.start("localhost", 2552) +// Actor.remote.register("hello-service", actorOf[HelloWorldActor]) +// } +// +// def main(args: Array[String]) = run +//} +// +//object ServerManagedRemoteActorClient { +// +// def run = { +// val actor = Actor.remote.actorFor("hello-service", "localhost", 2552) +// val result = actor !! "Hello" +// } +// +// def main(args: Array[String]) = run +//} +// diff --git a/akka-tutorials/akka-tutorial-first/pom.xml b/akka-tutorials/akka-tutorial-first/pom.xml index 8e25d972f3..1cec835a9c 100644 --- a/akka-tutorials/akka-tutorial-first/pom.xml +++ b/akka-tutorials/akka-tutorial-first/pom.xml @@ -13,7 +13,7 @@ - se.scalablesolutions.akka + com.typesafe.akka akka-actor 2.0-SNAPSHOT diff --git a/akka-tutorials/akka-tutorial-first/project/TutorialBuild.scala b/akka-tutorials/akka-tutorial-first/project/TutorialBuild.scala new file mode 100644 index 0000000000..5e5ef32493 --- /dev/null +++ b/akka-tutorials/akka-tutorial-first/project/TutorialBuild.scala @@ -0,0 +1,22 @@ +import sbt._ +import Keys._ + +object TutorialBuild extends Build { + lazy val buildSettings = Seq( + organization := "com.typesafe.akka", + version := "2.0-SNAPSHOT", + scalaVersion := "2.9.1" + ) + + lazy val akka = Project( + id = "akka-tutorial-first", + base = file("."), + settings = Defaults.defaultSettings ++ Seq( + libraryDependencies ++= Seq( + "com.typesafe.akka" % "akka-actor" % "2.0-SNAPSHOT", + "junit" % "junit" % "4.5" % "test", + "org.scalatest" % "scalatest_2.9.0" % "1.6.1" % "test", + "com.typesafe.akka" % "akka-testkit" % "2.0-SNAPSHOT" % "test") + ) + ) +} \ No newline at end of file diff --git a/akka-tutorials/akka-tutorial-first/project/build.properties b/akka-tutorials/akka-tutorial-first/project/build.properties index 4981c1c2c3..c6158f7be4 100644 --- a/akka-tutorials/akka-tutorial-first/project/build.properties +++ b/akka-tutorials/akka-tutorial-first/project/build.properties @@ -1,5 +1 @@ -project.organization=se.scalablesolutions.akka -project.name=akka-tutorial-first -project.version=2.0-SNAPSHOT -build.scala.versions=2.9.0 -sbt.version=0.7.7 +sbt.version=0.11.0 \ No newline at end of file diff --git a/akka-tutorials/akka-tutorial-first/project/build/Project.scala b/akka-tutorials/akka-tutorial-first/project/build/Project.scala deleted file mode 100644 index 975f2ce970..0000000000 --- a/akka-tutorials/akka-tutorial-first/project/build/Project.scala +++ /dev/null @@ -1,3 +0,0 @@ -import sbt._ - -class TutorialOneProject(info: ProjectInfo) extends DefaultProject(info) with AkkaProject diff --git a/akka-tutorials/akka-tutorial-first/project/plugins/Plugins.scala b/akka-tutorials/akka-tutorial-first/project/plugins/Plugins.scala deleted file mode 100644 index fb121fcd3e..0000000000 --- a/akka-tutorials/akka-tutorial-first/project/plugins/Plugins.scala +++ /dev/null @@ -1,6 +0,0 @@ -import sbt._ - -class Plugins(info: ProjectInfo) extends PluginDefinition(info) { - val akkaRepo = "Akka Repo" at "http://akka.io/repository" - val akkaPlugin = "se.scalablesolutions.akka" % "akka-sbt-plugin" % "2.0-SNAPSHOT" -} diff --git a/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java b/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java index ca8fe597f7..d6b9e8c1f1 100644 --- a/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java +++ b/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java @@ -1,182 +1,184 @@ -// * -// * Copyright (C) 2009-2011 Typesafe Inc. +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.tutorial.first.java; -// package akka.tutorial.first.java; +import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.actor.UntypedActor; +import akka.actor.UntypedActorFactory; +import akka.japi.Creator; +import akka.routing.*; -// import static akka.actor.Actors.poisonPill; -// import static java.util.Arrays.asList; +import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; -// import akka.actor.ActorRef; -// import akka.actor.Actors; -// import akka.actor.ActorSystem; -// import akka.actor.UntypedActor; -// import akka.actor.UntypedActorFactory; -// import akka.routing.RoutedProps; -// import akka.routing.RouterType; -// import akka.routing.LocalConnectionManager; -// import akka.routing.Routing; -// import akka.routing.Routing.Broadcast; -// import scala.collection.JavaConversions; +public class Pi { -// import java.util.LinkedList; -// import java.util.concurrent.CountDownLatch; + private static final ActorSystem system = ActorSystem.apply(); -// public class Pi { + public static void main(String[] args) throws Exception { + Pi pi = new Pi(); + pi.calculate(4, 10000, 10000); + } -// private static final ActorSystem system = new ActorSystem(); + // ==================== + // ===== Messages ===== + // ==================== + static class Calculate { + } -// public static void main(String[] args) throws Exception { -// Pi pi = new Pi(); -// pi.calculate(4, 10000, 10000); -// } + static class Work { + private final int start; + private final int nrOfElements; -// // ==================== -// // ===== Messages ===== -// // ==================== -// static class Calculate {} + public Work(int start, int nrOfElements) { + this.start = start; + this.nrOfElements = nrOfElements; + } -// static class Work { -// private final int start; -// private final int nrOfElements; + public int getStart() { + return start; + } -// public Work(int start, int nrOfElements) { -// this.start = start; -// this.nrOfElements = nrOfElements; -// } + public int getNrOfElements() { + return nrOfElements; + } + } -// public int getStart() { return start; } -// public int getNrOfElements() { return nrOfElements; } -// } + static class Result { + private final double value; -// static class Result { -// private final double value; + public Result(double value) { + this.value = value; + } -// public Result(double value) { -// this.value = value; -// } + public double getValue() { + return value; + } + } -// public double getValue() { return value; } -// } + // ================== + // ===== Worker ===== + // ================== + public static class Worker extends UntypedActor { -// // ================== -// // ===== Worker ===== -// // ================== -// static class Worker extends UntypedActor { + // define the work + private double calculatePiFor(int start, int nrOfElements) { + double acc = 0.0; + for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) { + acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1); + } + return acc; + } -// // define the work -// private double calculatePiFor(int start, int nrOfElements) { -// double acc = 0.0; -// for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) { -// acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1); -// } -// return acc; -// } + // message handler + public void onReceive(Object message) { + if (message instanceof Work) { + Work work = (Work) message; -// // message handler -// public void onReceive(Object message) { -// if (message instanceof Work) { -// Work work = (Work) message; + // perform the work + double result = calculatePiFor(work.getStart(), work.getNrOfElements()); -// // perform the work -// double result = calculatePiFor(work.getStart(), work.getNrOfElements()); + // reply with the result + getSender().tell(new Result(result)); -// // reply with the result -// getSender().tell(new Result(result)); + } else throw new IllegalArgumentException("Unknown message [" + message + "]"); + } + } -// } else throw new IllegalArgumentException("Unknown message [" + message + "]"); -// } -// } + // ================== + // ===== Master ===== + // ================== + public static class Master extends UntypedActor { + private final int nrOfMessages; + private final int nrOfElements; + private final CountDownLatch latch; -// // ================== -// // ===== Master ===== -// // ================== -// static class Master extends UntypedActor { -// private final int nrOfMessages; -// private final int nrOfElements; -// private final CountDownLatch latch; + private double pi; + private int nrOfResults; + private long start; -// private double pi; -// private int nrOfResults; -// private long start; + private ActorRef router; -// private ActorRef router; + public Master(final int nrOfWorkers, int nrOfMessages, int nrOfElements, CountDownLatch latch) { + this.nrOfMessages = nrOfMessages; + this.nrOfElements = nrOfElements; + this.latch = latch; + Creator routerCreator = new Creator() { + public Router create() { + return new RoundRobinRouter(); + } + }; + LinkedList actors = new LinkedList() { + { + for (int i = 0; i < nrOfWorkers; i++) add(system.actorOf(Worker.class)); + } + }; + RoutedProps props = new RoutedProps(routerCreator, new LocalConnectionManager(actors), new akka.actor.Timeout(-1), true); + router = new RoutedActorRef(system, props, getSelf(), "pi"); + } -// public Master(int nrOfWorkers, int nrOfMessages, int nrOfElements, CountDownLatch latch) { -// this.nrOfMessages = nrOfMessages; -// this.nrOfElements = nrOfElements; -// this.latch = latch; + // message handler + public void onReceive(Object message) { -// LinkedList workers = new LinkedList(); -// for (int i = 0; i < nrOfWorkers; i++) { -// ActorRef worker = system.actorOf(Worker.class); -// workers.add(worker); -// } + if (message instanceof Calculate) { -// router = system.actorOf(new RoutedProps().withRoundRobinRouter().withLocalConnections(workers), "pi"); -// } + // schedule work + for (int start = 0; start < nrOfMessages; start++) { + router.tell(new Work(start, nrOfElements), getSelf()); + } -// // message handler -// public void onReceive(Object message) { + } else if (message instanceof Result) { -// if (message instanceof Calculate) { -// // schedule work -// for (int start = 0; start < nrOfMessages; start++) { -// router.tell(new Work(start, nrOfElements), getSelf()); -// } + // handle result from the worker + Result result = (Result) message; + pi += result.getValue(); + nrOfResults += 1; + if (nrOfResults == nrOfMessages) getSelf().stop(); -// // send a PoisonPill to all workers telling them to shut down themselves -// router.tell(new Broadcast(poisonPill())); + } else throw new IllegalArgumentException("Unknown message [" + message + "]"); + } -// // send a PoisonPill to the router, telling him to shut himself down -// router.tell(poisonPill()); + @Override + public void preStart() { + start = System.currentTimeMillis(); + } -// } else if (message instanceof Result) { + @Override + public void postStop() { + // tell the world that the calculation is complete + System.out.println(String.format( + "\n\tPi estimate: \t\t%s\n\tCalculation time: \t%s millis", + pi, (System.currentTimeMillis() - start))); + latch.countDown(); + } + } -// // handle result from the worker -// Result result = (Result) message; -// pi += result.getValue(); -// nrOfResults += 1; -// if (nrOfResults == nrOfMessages) getSelf().stop(); + // ================== + // ===== Run it ===== + // ================== + public void calculate(final int nrOfWorkers, final int nrOfElements, final int nrOfMessages) + throws Exception { -// } else throw new IllegalArgumentException("Unknown message [" + message + "]"); -// } + // this latch is only plumbing to know when the calculation is completed + final CountDownLatch latch = new CountDownLatch(1); -// @Override -// public void preStart() { -// start = System.currentTimeMillis(); -// } + // create the master + ActorRef master = system.actorOf(new UntypedActorFactory() { + public UntypedActor create() { + return new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch); + } + }); -// @Override -// public void postStop() { -// // tell the world that the calculation is complete -// System.out.println(String.format( -// "\n\tPi estimate: \t\t%s\n\tCalculation time: \t%s millis", -// pi, (System.currentTimeMillis() - start))); -// latch.countDown(); -// } -// } + // start the calculation + master.tell(new Calculate()); -// // ================== -// // ===== Run it ===== -// // ================== -// public void calculate(final int nrOfWorkers, final int nrOfElements, final int nrOfMessages) -// throws Exception { + // wait for master to shut down + latch.await(); -// // this latch is only plumbing to know when the calculation is completed -// final CountDownLatch latch = new CountDownLatch(1); - -// // create the master -// ActorRef master = system.actorOf(new UntypedActorFactory() { -// public UntypedActor create() { -// return new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch); -// } -// }); - -// // start the calculation -// master.tell(new Calculate()); - -// // wait for master to shut down -// latch.await(); -// } -// } + // Shut down the system + system.stop(); + } +} diff --git a/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala b/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala index 836f766e12..d7f932a053 100644 --- a/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala +++ b/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala @@ -1,113 +1,114 @@ -// /** -// * Copyright (C) 2009-2011 Typesafe Inc. -// */ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.tutorial.first.scala -// package akka.tutorial.first.scala +import java.util.concurrent.CountDownLatch +import akka.routing.{ RoutedActorRef, LocalConnectionManager, RoundRobinRouter, RoutedProps } +import akka.actor.{ ActorSystemImpl, Actor, ActorSystem } -// import akka.actor.{ Actor, PoisonPill, ActorSystem } -// import Actor._ -// import java.util.concurrent.CountDownLatch -// import akka.routing.Routing.Broadcast -// import akka.routing.{ RoutedProps, Routing } +object Pi extends App { -// object Pi extends App { + val system = ActorSystem() -// val system = ActorSystem() + // Initiate the calculation + calculate(nrOfWorkers = 4, nrOfElements = 10000, nrOfMessages = 10000) -// calculate(nrOfWorkers = 4, nrOfElements = 10000, nrOfMessages = 10000) + // ==================== + // ===== Messages ===== + // ==================== + sealed trait PiMessage -// // ==================== -// // ===== Messages ===== -// // ==================== -// sealed trait PiMessage + case object Calculate extends PiMessage -// case object Calculate extends PiMessage + case class Work(start: Int, nrOfElements: Int) extends PiMessage -// case class Work(start: Int, nrOfElements: Int) extends PiMessage + case class Result(value: Double) extends PiMessage -// case class Result(value: Double) extends PiMessage + // ================== + // ===== Worker ===== + // ================== + class Worker extends Actor { -// // ================== -// // ===== Worker ===== -// // ================== -// class Worker extends Actor { + // define the work + 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 + } -// // define the work -// 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 -// } + def receive = { + case Work(start, nrOfElements) ⇒ sender ! Result(calculatePiFor(start, nrOfElements)) // perform the work + } + } -// def receive = { -// case Work(start, nrOfElements) ⇒ sender ! Result(calculatePiFor(start, nrOfElements)) // perform the work -// } -// } + // ================== + // ===== Master ===== + // ================== + class Master(nrOfWorkers: Int, nrOfMessages: Int, nrOfElements: Int, latch: CountDownLatch) + extends Actor { -// // ================== -// // ===== Master ===== -// // ================== -// class Master(nrOfWorkers: Int, nrOfMessages: Int, nrOfElements: Int, latch: CountDownLatch) -// extends Actor { + var pi: Double = _ + var nrOfResults: Int = _ + var start: Long = _ -// var pi: Double = _ -// var nrOfResults: Int = _ -// var start: Long = _ + // create the workers + val workers = Vector.fill(nrOfWorkers)(system.actorOf[Worker]) -// // create the workers -// val workers = Vector.fill(nrOfWorkers)(system.actorOf[Worker]) + // wrap them with a load-balancing router + val props = RoutedProps(routerFactory = () ⇒ new RoundRobinRouter, connectionManager = new LocalConnectionManager(workers)) + val router = new RoutedActorRef(system, props, self, "pi") -// // wrap them with a load-balancing router -// val router = system.actorOf(RoutedProps().withRoundRobinRouter.withLocalConnections(workers), "pi") + // message handler + def receive = { + case Calculate ⇒ + // schedule work + for (i ← 0 until nrOfMessages) router ! Work(i * nrOfElements, nrOfElements) + case Result(value) ⇒ + // handle result from the worker + pi += value + nrOfResults += 1 -// // message handler -// def receive = { -// case Calculate ⇒ -// // schedule work -// for (i ← 0 until nrOfMessages) router ! Work(i * nrOfElements, nrOfElements) + // Stop this actor and all its supervised children + if (nrOfResults == nrOfMessages) self.stop() + } -// // send a PoisonPill to all workers telling them to shut down themselves -// router ! Broadcast(PoisonPill) + override def preStart() { + start = System.currentTimeMillis + } -// // send a PoisonPill to the router, telling him to shut himself down -// router ! PoisonPill + override def postStop() { + // tell the world that the calculation is complete + println( + "\n\tPi estimate: \t\t%s\n\tCalculation time: \t%s millis" + .format(pi, (System.currentTimeMillis - start))) + latch.countDown() + } + } -// case Result(value) ⇒ -// // handle result from the worker -// pi += value -// nrOfResults += 1 -// if (nrOfResults == nrOfMessages) self.stop() -// } + object Master { + val impl = system.asInstanceOf[ActorSystemImpl] + } -// override def preStart() { -// start = System.currentTimeMillis -// } + // ================== + // ===== Run it ===== + // ================== + def calculate(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int) { -// override def postStop() { -// // tell the world that the calculation is complete -// println( -// "\n\tPi estimate: \t\t%s\n\tCalculation time: \t%s millis" -// .format(pi, (System.currentTimeMillis - start))) -// latch.countDown() -// } -// } + // this latch is only plumbing to know when the calculation is completed + val latch = new CountDownLatch(1) -// // ================== -// // ===== Run it ===== -// // ================== -// def calculate(nrOfWorkers: Int, nrOfElements: Int, nrOfMessages: Int) { + // create the master + val master = system.actorOf(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) -// // this latch is only plumbing to know when the calculation is completed -// val latch = new CountDownLatch(1) + // start the calculation + master ! Calculate -// // create the master -// val master = system.actorOf(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) + // wait for master to shut down + latch.await() -// // start the calculation -// master ! Calculate - -// // wait for master to shut down -// latch.await() -// } -// } + // Shut down the system + system.stop() + } +} diff --git a/akka-tutorials/akka-tutorial-first/src/test/scala/WorkerSpec.scala b/akka-tutorials/akka-tutorial-first/src/test/scala/WorkerSpec.scala new file mode 100644 index 0000000000..608ba55481 --- /dev/null +++ b/akka-tutorials/akka-tutorial-first/src/test/scala/WorkerSpec.scala @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2009-2011 Typesafe Inc. + */ +package akka.tutorial.first.scala + +import org.junit.runner.RunWith +import org.scalatest.matchers.MustMatchers +import org.scalatest.WordSpec +import akka.testkit.TestActorRef +import akka.tutorial.first.scala.Pi.Worker +import akka.actor.ActorSystem + +@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) +class WorkerSpec extends WordSpec with MustMatchers { + + implicit def system = ActorSystem() + + "Worker" must { + "calculate pi correctly" in { + val testActor = TestActorRef[Worker] + val actor = testActor.underlyingActor + actor.calculatePiFor(0, 0) must equal(0.0) + actor.calculatePiFor(1, 1) must equal(-1.3333333333333333) + } + } +} \ No newline at end of file diff --git a/project/AkkaBuild.scala b/project/AkkaBuild.scala index dd09fe3c80..e4fb06a8cc 100644 --- a/project/AkkaBuild.scala +++ b/project/AkkaBuild.scala @@ -243,23 +243,31 @@ object AkkaBuild extends Build { id = "akka-samples", base = file("akka-samples"), settings = parentSettings, - aggregate = Seq(fsmSample) - // aggregate = Seq(fsmSample, camelSample) + aggregate = Seq(antsSample, helloSample, osgiSample, fsmSample) ) - // lazy val antsSample = Project( - // id = "akka-sample-ants", - // base = file("akka-samples/akka-sample-ants"), - // dependencies = Seq(stm), - // settings = defaultSettings - // ) + lazy val antsSample = Project( + id = "akka-sample-ants", + base = file("akka-samples/akka-sample-ants"), + dependencies = Seq(actor, stm), + settings = defaultSettings + ) - // lazy val chatSample = Project( - // id = "akka-sample-chat", - // base = file("akka-samples/akka-sample-chat"), - // dependencies = Seq(cluster), - // settings = defaultSettings - // ) + lazy val helloSample = Project( + id = "akka-sample-hello", + base = file("akka-samples/akka-sample-hello"), + dependencies = Seq(actor), + settings = defaultSettings + ) + + lazy val osgiSample = Project( + id = "akka-sample-osgi", + base = file("akka-samples/akka-sample-osgi"), + dependencies = Seq(actor), + settings = defaultSettings ++ Seq( + libraryDependencies ++= Dependencies.sampleOsgi + ) + ) lazy val fsmSample = Project( id = "akka-sample-fsm", @@ -268,6 +276,21 @@ object AkkaBuild extends Build { settings = defaultSettings ) + // lazy val chatSample = Project( + // id = "akka-sample-chat", + // base = file("akka-samples/akka-sample-chat"), + // dependencies = Seq(cluster), + // settings = defaultSettings + // ) + + // lazy val samples = Project( + // id = "akka-samples", + // base = file("akka-samples"), + // settings = parentSettings, + // aggregate = Seq(fsmSample) + // // aggregate = Seq(fsmSample, camelSample) + // ) + // lazy val camelSample = Project( // id = "akka-sample-camel", // base = file("akka-samples/akka-sample-camel"), @@ -277,13 +300,6 @@ object AkkaBuild extends Build { // ) // ) - // lazy val helloSample = Project( - // id = "akka-sample-hello", - // base = file("akka-samples/akka-sample-hello"), - // dependencies = Seq(kernel), - // settings = defaultSettings - // ) - // lazy val remoteSample = Project( // id = "akka-sample-remote", // base = file("akka-samples/akka-sample-remote"), @@ -295,22 +311,24 @@ object AkkaBuild extends Build { id = "akka-tutorials", base = file("akka-tutorials"), settings = parentSettings, - aggregate = Seq(firstTutorial, secondTutorial) + aggregate = Seq(firstTutorial) ) lazy val firstTutorial = Project( id = "akka-tutorial-first", base = file("akka-tutorials/akka-tutorial-first"), - dependencies = Seq(actor), - settings = defaultSettings + dependencies = Seq(actor, testkit), + settings = defaultSettings ++ Seq( + libraryDependencies ++= Dependencies.tutorials + ) ) - lazy val secondTutorial = Project( - id = "akka-tutorial-second", - base = file("akka-tutorials/akka-tutorial-second"), - dependencies = Seq(actor), - settings = defaultSettings - ) + // lazy val secondTutorial = Project( + // id = "akka-tutorial-second", + // base = file("akka-tutorials/akka-tutorial-second"), + // dependencies = Seq(actor), + // settings = defaultSettings + // ) lazy val docs = Project( id = "akka-docs", @@ -448,6 +466,10 @@ object Dependencies { // val sampleCamel = Seq(camelCore, camelSpring, commonsCodec, Runtime.camelJms, Runtime.activemq, Runtime.springJms, // Test.junit, Test.scalatest, Test.logback) + val sampleOsgi = Seq(osgi) + + val tutorials = Seq(Test.scalatest, Test.junit) + val docs = Seq(Test.scalatest, Test.junit) }