diff --git a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala index 6f08ba6dcf..83d5cebac4 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala @@ -63,7 +63,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "no router" must { "be started when constructed" in { - val routedActor = system.actorOf(Props(new TestActor).withRouter(NoRouter)) + val routedActor = system.actorOf(Props[TestActor].withRouter(NoRouter)) routedActor.isTerminated must be(false) } @@ -91,7 +91,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "round robin router" must { "be started when constructed" in { - val routedActor = system.actorOf(Props(new TestActor).withRouter(RoundRobinRouter(nrOfInstances = 1))) + val routedActor = system.actorOf(Props[TestActor].withRouter(RoundRobinRouter(nrOfInstances = 1))) routedActor.isTerminated must be(false) } @@ -119,7 +119,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { actors = actors :+ actor } - val routedActor = system.actorOf(Props(new TestActor).withRouter(RoundRobinRouter(targets = actors))) + val routedActor = system.actorOf(Props[TestActor].withRouter(RoundRobinRouter(targets = actors))) //send messages to the actor. for (i ← 0 until iterationCount) { @@ -157,7 +157,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { } })) - val routedActor = system.actorOf(Props(new TestActor).withRouter(RoundRobinRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(RoundRobinRouter(targets = List(actor1, actor2)))) routedActor ! Broadcast(1) routedActor ! Broadcast("end") @@ -172,7 +172,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "random router" must { "be started when constructed" in { - val routedActor = system.actorOf(Props(new TestActor).withRouter(RandomRouter(nrOfInstances = 1))) + val routedActor = system.actorOf(Props[TestActor].withRouter(RandomRouter(nrOfInstances = 1))) routedActor.isTerminated must be(false) } @@ -195,7 +195,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { } })) - val routedActor = system.actorOf(Props(new TestActor).withRouter(RandomRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(RandomRouter(targets = List(actor1, actor2)))) routedActor ! Broadcast(1) routedActor ! Broadcast("end") @@ -209,7 +209,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "broadcast router" must { "be started when constructed" in { - val routedActor = system.actorOf(Props(new TestActor).withRouter(BroadcastRouter(nrOfInstances = 1))) + val routedActor = system.actorOf(Props[TestActor].withRouter(BroadcastRouter(nrOfInstances = 1))) routedActor.isTerminated must be(false) } @@ -232,7 +232,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { } })) - val routedActor = system.actorOf(Props(new TestActor).withRouter(BroadcastRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(BroadcastRouter(targets = List(actor1, actor2)))) routedActor ! 1 routedActor ! "end" @@ -263,7 +263,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { } })) - val routedActor = system.actorOf(Props(new TestActor).withRouter(BroadcastRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(BroadcastRouter(targets = List(actor1, actor2)))) routedActor ? 1 routedActor ! "end" @@ -277,7 +277,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { "Scatter-gather router" must { "be started when constructed" in { - val routedActor = system.actorOf(Props(new TestActor).withRouter(ScatterGatherFirstCompletedRouter(targets = List(newActor(0))))) + val routedActor = system.actorOf(Props[TestActor].withRouter(ScatterGatherFirstCompletedRouter(targets = List(newActor(0))))) routedActor.isTerminated must be(false) } @@ -300,7 +300,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { } })) - val routedActor = system.actorOf(Props(new TestActor).withRouter(ScatterGatherFirstCompletedRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(ScatterGatherFirstCompletedRouter(targets = List(actor1, actor2)))) routedActor ! Broadcast(1) routedActor ! Broadcast("end") @@ -314,7 +314,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender { val shutdownLatch = new TestLatch(1) val actor1 = newActor(1, Some(shutdownLatch)) val actor2 = newActor(22, Some(shutdownLatch)) - val routedActor = system.actorOf(Props(new TestActor).withRouter(ScatterGatherFirstCompletedRouter(targets = List(actor1, actor2)))) + val routedActor = system.actorOf(Props[TestActor].withRouter(ScatterGatherFirstCompletedRouter(targets = List(actor1, actor2)))) routedActor ! Broadcast(Stop(Some(1))) shutdownLatch.await diff --git a/akka-actor/src/main/scala/akka/actor/Props.scala b/akka-actor/src/main/scala/akka/actor/Props.scala index 9824803aea..e96a5b37c9 100644 --- a/akka-actor/src/main/scala/akka/actor/Props.scala +++ b/akka-actor/src/main/scala/akka/actor/Props.scala @@ -8,11 +8,13 @@ import akka.dispatch._ import akka.japi.Creator import akka.util._ import collection.immutable.Stack -import akka.routing.{ NoRouter, RouterConfig } +import akka.routing._ /** * Factory for Props instances. + * * Props is a ActorRef configuration object, that is thread safe and fully sharable. + * * Used when creating new actors through; ActorSystem.actorOf and ActorContext.actorOf. */ object Props { @@ -47,6 +49,8 @@ object Props { /** * Returns a Props that has default values except for "creator" which will be a function that creates an instance * of the supplied type using the default constructor. + * + * Scala API. */ def apply[T <: Actor: ClassManifest]: Props = default.withCreator(implicitly[ClassManifest[T]].erasure.asInstanceOf[Class[_ <: Actor]].newInstance) @@ -61,6 +65,8 @@ object Props { /** * Returns a Props that has default values except for "creator" which will be a function that creates an instance * using the supplied thunk. + * + * Scala API. */ def apply(creator: ⇒ Actor): Props = default.withCreator(creator) @@ -87,7 +93,16 @@ object Props { * {{{ * val props = Props[MyActor] * val props = Props(new MyActor) + * val props = Props( + * creator = .., + * dispatcher = .., + * timeout = .., + * faultHandler = .., + * routerConfig = .. + * ) + * val props = Props().withCreator(new MyActor) * val props = Props[MyActor].withTimeout(timeout) + * val props = Props[MyActor].withRouter(RoundRobinRouter(..)) * val props = Props[MyActor].withFaultHandler(OneForOneStrategy { * case e: IllegalStateException ⇒ Resume * }) @@ -103,19 +118,20 @@ object Props { * } * }); * Props props = new Props().withCreator(new UntypedActorFactory() { ... }); - * Props props = new Props().withTimeout(timeout); - * Props props = new Props().withFaultHandler(new OneForOneStrategy(...)); + * Props props = new Props(MyActor.class).withTimeout(timeout); + * Props props = new Props(MyActor.class).withFaultHandler(new OneForOneStrategy(...)); + * Props props = new Props(MyActor.class).withRouter(new RoundRobinRouter(..)); * }}} */ -case class Props(creator: () ⇒ Actor = Props.defaultCreator, - @transient dispatcher: MessageDispatcher = Props.defaultDispatcher, - timeout: Timeout = Props.defaultTimeout, - faultHandler: FaultHandlingStrategy = Props.defaultFaultHandler, - routerConfig: RouterConfig = Props.defaultRoutedProps) { +case class Props( + creator: () ⇒ Actor = Props.defaultCreator, + @transient dispatcher: MessageDispatcher = Props.defaultDispatcher, + timeout: Timeout = Props.defaultTimeout, + faultHandler: FaultHandlingStrategy = Props.defaultFaultHandler, + routerConfig: RouterConfig = Props.defaultRoutedProps) { /** * No-args constructor that sets all the default values. - * Java API. */ def this() = this( creator = Props.defaultCreator, @@ -144,43 +160,42 @@ case class Props(creator: () ⇒ Actor = Props.defaultCreator, /** * Returns a new Props with the specified creator set. + * * Scala API. */ def withCreator(c: ⇒ Actor) = copy(creator = () ⇒ c) /** * Returns a new Props with the specified creator set. + * * Java API. */ def withCreator(c: Creator[Actor]) = copy(creator = () ⇒ c.create) /** * Returns a new Props with the specified creator set. + * * Java API. */ def withCreator(c: Class[_ <: Actor]) = copy(creator = () ⇒ c.newInstance) /** * Returns a new Props with the specified dispatcher set. - * Java API. */ def withDispatcher(d: MessageDispatcher) = copy(dispatcher = d) /** - * Returns a new Props with the specified timeout set - * Java API. + * Returns a new Props with the specified timeout set. */ def withTimeout(t: Timeout) = copy(timeout = t) /** * Returns a new Props with the specified faulthandler set. - * Java API. */ def withFaultHandler(f: FaultHandlingStrategy) = copy(faultHandler = f) /** - * Returns a new Props with the specified router config set - * Java API + * Returns a new Props with the specified router config set. */ def withRouter(r: RouterConfig) = copy(routerConfig = r) } diff --git a/akka-actor/src/main/scala/akka/routing/package.scala b/akka-actor/src/main/scala/akka/routing/package.scala index 1f2e343a33..44662856b1 100644 --- a/akka-actor/src/main/scala/akka/routing/package.scala +++ b/akka-actor/src/main/scala/akka/routing/package.scala @@ -5,7 +5,5 @@ package akka package object routing { - type Route = PartialFunction[(akka.actor.ActorRef, Any), Iterable[Destination]] - -} \ No newline at end of file +} diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index 1093f58caf..e5fd2f9205 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -4,24 +4,21 @@ package akka.docs.actor; import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Props; - //#imports //#import-future import akka.dispatch.Future; import akka.dispatch.Await; import akka.util.Duration; - +import akka.util.Timeout; //#import-future //#import-actors import static akka.actor.Actors.*; - //#import-actors //#import-procedure import akka.japi.Procedure; - //#import-procedure import akka.actor.Props; @@ -38,6 +35,25 @@ import static org.junit.Assert.*; public class UntypedActorDocTestBase { + @Test + public void createProps() { + //#creating-props-config + Props props1 = new Props(); + Props props2 = new Props(MyUntypedActor.class); + Props props3 = new Props(new UntypedActorFactory() { + public UntypedActor create() { + return new MyUntypedActor(); + } + }); + Props props4 = props1.withCreator(new UntypedActorFactory() { + public UntypedActor create() { + return new MyUntypedActor(); + } + }); + Props props5 = props4.withTimeout(new Timeout(1000)); + //#creating-props-config + } + @Test public void systemActorOf() { //#system-actorOf @@ -78,8 +94,9 @@ public class UntypedActorDocTestBase { ActorSystem system = ActorSystem.create("MySystem"); //#creating-props MessageDispatcher dispatcher = system.dispatcherFactory().lookup("my-dispatcher"); - ActorRef myActor = system.actorOf(new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), - "myactor"); + ActorRef myActor = system.actorOf( + new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), + "myactor"); //#creating-props myActor.tell("test"); system.shutdown(); diff --git a/akka-docs/java/untyped-actors.rst b/akka-docs/java/untyped-actors.rst index 8ad7a7f7b2..34a0058c76 100644 --- a/akka-docs/java/untyped-actors.rst +++ b/akka-docs/java/untyped-actors.rst @@ -39,6 +39,23 @@ Here is an example: .. includecode:: code/akka/docs/actor/MyUntypedActor.java#my-untyped-actor +Props +----- + +``Props`` is a configuration class to specify options for the creation +of actors. Here are some examples on how to create a ``Props`` instance. + +.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-props-config + + +Creating Actors with Props +-------------------------- + +Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method. + +.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-props + + Creating Actors with default constructor ---------------------------------------- @@ -76,26 +93,16 @@ add initialization code for the actor. Creating Actors with non-default constructor -------------------------------------------- -If your UntypedActor has a constructor that takes parameters then you can't create it using 'actorOf(clazz)'. -Instead you can use a variant of ``actorOf`` that takes an instance of an 'UntypedActorFactory' -in which you can create the Actor in any way you like. If you use this method then you to make sure that -no one can get a reference to the actor instance. If they can get a reference it then they can -touch state directly in bypass the whole actor dispatching mechanism and create race conditions -which can lead to corrupt data. +If your UntypedActor has a constructor that takes parameters then you can't create it using +'actorOf(new Props(clazz))'. Then you can instead pass in 'new Props(new UntypedActorFactory() {..})' +in which you can create the Actor in any way you like. Here is an example: .. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-constructor -This way of creating the Actor is also great for integrating with Dependency Injection (DI) frameworks like Guice or Spring. - -Creating Actors with Props --------------------------- - -``Props`` is a configuration object to specify additional things for the actor to -be created, such as the ``MessageDispatcher``. - -.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java#creating-props +This way of creating the Actor is also great for integrating with Dependency Injection +(DI) frameworks like Guice or Spring. UntypedActor API diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index dcb7ed2795..1dfe7a89ec 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -95,11 +95,19 @@ Here is an example: .. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-constructor +Props +----- + +``Props`` is a configuration class to specify options for the creation +of actors. Here are some examples on how to create a ``Props`` instance. + +.. includecode:: code/ActorDocSpec.scala#creating-props-config + + Creating Actors with Props -------------------------- -``Props`` is a configuration object to specify additional things for the actor to -be created, such as the ``MessageDispatcher``. +Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method. .. includecode:: code/akka/docs/actor/ActorDocSpec.scala#creating-props diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index 68733d2009..cf24d6a79b 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -15,6 +15,7 @@ import akka.actor.ActorSystem import org.scalatest.{ BeforeAndAfterAll, WordSpec } import org.scalatest.matchers.MustMatchers import akka.testkit._ +import akka.util._ import akka.util.duration._ //#my-actor @@ -187,6 +188,23 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { system.stop(myActor) } + "creating a Props config" in { + val dispatcher = system.dispatcherFactory.lookup("my-dispatcher") + //#creating-props-config + import akka.actor.Props + val props1 = Props() + val props2 = Props[MyActor] + val props3 = Props(new MyActor) + val props4 = Props( + creator = { () ⇒ new MyActor }, + dispatcher = dispatcher, + timeout = Timeout(100)) + val props5 = props1.withCreator(new MyActor) + val props6 = props5.withDispatcher(dispatcher) + val props7 = props6.withTimeout(Timeout(100)) + //#creating-props-config + } + "creating actor with Props" in { //#creating-props import akka.actor.Props 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 0dddc16654..094fb34045 100644 --- a/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala +++ b/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala @@ -50,8 +50,7 @@ object Pi extends App { var start: Long = _ //#create-router - val router = context.actorOf(Props(new Worker).withRouter( - RoundRobinRouter(nrOfInstances = nrOfWorkers)), "pi") + val router = context.actorOf(Props[Worker].withRouter(RoundRobinRouter(nrOfWorkers)), "pi") //#create-router //#master-receive