Updated after feedback. See #1063
This commit is contained in:
parent
41ce42c8f7
commit
d68777e76e
9 changed files with 73 additions and 138 deletions
|
|
@ -342,12 +342,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
|
||||||
|
|
||||||
"custom router" must {
|
"custom router" must {
|
||||||
"be started when constructed" in {
|
"be started when constructed" in {
|
||||||
val routedActor = system.actorOf(Props(new TestActor).withRouter(VoteCountRouter()))
|
val routedActor = system.actorOf(Props[TestActor].withRouter(VoteCountRouter()))
|
||||||
routedActor.isTerminated must be(false)
|
routedActor.isTerminated must be(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
"count votes as intended - not as in Florida" in {
|
"count votes as intended - not as in Florida" in {
|
||||||
val routedActor = system.actorOf(Props(new TestActor).withRouter(VoteCountRouter()))
|
val routedActor = system.actorOf(Props[TestActor].withRouter(VoteCountRouter()))
|
||||||
routedActor ! DemocratVote
|
routedActor ! DemocratVote
|
||||||
routedActor ! DemocratVote
|
routedActor ! DemocratVote
|
||||||
routedActor ! RepublicanVote
|
routedActor ! RepublicanVote
|
||||||
|
|
@ -375,20 +375,20 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
|
||||||
|
|
||||||
//#crActors
|
//#crActors
|
||||||
class DemocratActor extends Actor {
|
class DemocratActor extends Actor {
|
||||||
val counter = new AtomicInteger(0)
|
var counter = 0
|
||||||
|
|
||||||
def receive = {
|
def receive = {
|
||||||
case DemocratVote ⇒ counter.incrementAndGet()
|
case DemocratVote ⇒ counter += 1
|
||||||
case DemocratCountResult ⇒ sender ! counter.get
|
case DemocratCountResult ⇒ sender ! counter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RepublicanActor extends Actor {
|
class RepublicanActor extends Actor {
|
||||||
val counter = new AtomicInteger(0)
|
var counter = 0
|
||||||
|
|
||||||
def receive = {
|
def receive = {
|
||||||
case RepublicanVote ⇒ counter.incrementAndGet()
|
case RepublicanVote ⇒ counter += 1
|
||||||
case RepublicanCountResult ⇒ sender ! counter.get
|
case RepublicanCountResult ⇒ sender ! counter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#crActors
|
//#crActors
|
||||||
|
|
@ -401,8 +401,8 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
|
||||||
def createRoute(props: Props,
|
def createRoute(props: Props,
|
||||||
actorContext: ActorContext,
|
actorContext: ActorContext,
|
||||||
ref: RoutedActorRef): Route = {
|
ref: RoutedActorRef): Route = {
|
||||||
val democratActor = actorContext.actorOf(Props(new DemocratActor), "d")
|
val democratActor = actorContext.actorOf(Props[DemocratActor], "d")
|
||||||
val republicanActor = actorContext.actorOf(Props(new RepublicanActor), "r")
|
val republicanActor = actorContext.actorOf(Props[RepublicanActor], "r")
|
||||||
val routees = Vector[ActorRef](democratActor, republicanActor)
|
val routees = Vector[ActorRef](democratActor, republicanActor)
|
||||||
|
|
||||||
//#crRegisterRoutees
|
//#crRegisterRoutees
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,7 @@
|
||||||
|
|
||||||
|
.. _routing-java:
|
||||||
|
|
||||||
Routing (Java)
|
Routing (Java)
|
||||||
==============
|
==============
|
||||||
|
|
||||||
UntypedDispatcher
|
TDB
|
||||||
-----------------
|
|
||||||
|
|
||||||
An UntypedDispatcher is an actor that routes incoming messages to outbound actors.
|
|
||||||
|
|
||||||
.. code-block:: java
|
|
||||||
|
|
||||||
import static akka.actor.Actors.*;
|
|
||||||
import akka.actor.*;
|
|
||||||
import akka.routing.*;
|
|
||||||
|
|
||||||
//A Pinger is an UntypedActor that prints "Pinger: <message>"
|
|
||||||
class Pinger extends UntypedActor {
|
|
||||||
public void onReceive(Object message) throws Exception {
|
|
||||||
System.out.println("Pinger: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//A Ponger is an UntypedActor that prints "Ponger: <message>"
|
|
||||||
class Ponger extends UntypedActor {
|
|
||||||
public void onReceive(Object message) throws Exception {
|
|
||||||
System.out.println("Ponger: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MyRouter extends UntypedRouter {
|
|
||||||
private ActorRef pinger = actorOf(new Props(Pinger.class));
|
|
||||||
private ActorRef ponger = actorOf(new Props(Ponger.class));
|
|
||||||
|
|
||||||
//Route Ping-messages to the pinger, and Pong-messages to the ponger
|
|
||||||
public ActorRef route(Object message) {
|
|
||||||
if("Ping".equals(message)) return pinger;
|
|
||||||
else if("Pong".equals(message)) return ponger;
|
|
||||||
else throw new IllegalArgumentException("I do not understand " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActorRef router = actorOf(new Props(MyRouter.class));
|
|
||||||
router.tell("Ping"); //Prints "Pinger: Ping"
|
|
||||||
router.tell("Pong"); //Prints "Ponger: Pong"
|
|
||||||
|
|
||||||
UntypedLoadBalancer
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
An UntypedLoadBalancer is an actor that forwards messages it receives to a boundless sequence of destination actors.
|
|
||||||
|
|
||||||
.. code-block:: java
|
|
||||||
|
|
||||||
import static akka.actor.Actors.*;
|
|
||||||
import akka.actor.*;
|
|
||||||
import akka.routing.*;
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
|
|
||||||
//A Pinger is an UntypedActor that prints "Pinger: <message>"
|
|
||||||
class Pinger extends UntypedActor {
|
|
||||||
public void onReceive(Object message) throws Exception {
|
|
||||||
System.out.println("Pinger: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//A Ponger is an UntypedActor that prints "Ponger: <message>"
|
|
||||||
class Ponger extends UntypedActor {
|
|
||||||
public void onReceive(Object message) throws Exception {
|
|
||||||
System.out.println("Ponger: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Our load balancer, sends messages to a pinger, then a ponger, rinse and repeat.
|
|
||||||
public class MyLoadBalancer extends UntypedLoadBalancer {
|
|
||||||
private InfiniteIterator<ActorRef> actors = new CyclicIterator<ActorRef>(asList(
|
|
||||||
actorOf(new Props(Pinger.class)),
|
|
||||||
actorOf(new Props(Ponger.class))
|
|
||||||
));
|
|
||||||
|
|
||||||
public InfiniteIterator<ActorRef> seq() {
|
|
||||||
return actors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActorRef balancer = actorOf(new Props(MyLoadBalancer.class));
|
|
||||||
balancer.tell("Pong"); //Prints "Pinger: Pong"
|
|
||||||
balancer.tell("Ping"); //Prints "Ponger: Ping"
|
|
||||||
balancer.tell("Ping"); //Prints "Pinger: Ping"
|
|
||||||
balancer.tell("Pong"); //Prints "Ponger: Pong
|
|
||||||
|
|
||||||
You can also send a 'new Routing.Broadcast(msg)' message to the router to have it be broadcasted out to all the actors it represents.
|
|
||||||
|
|
||||||
.. code-block:: java
|
|
||||||
|
|
||||||
balancer.tell(new Routing.Broadcast(new PoisonPill()));
|
|
||||||
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import akka.routing.{ BasicNoBackoffFilter, SmallestMailboxSelector, DefaultActorPool }
|
import akka.routing.{ BasicNoBackoffFilter, SmallestMailboxSelector, DefaultActorPool }
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import akka.actor.ActorRef
|
import akka.actor.ActorRef
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import akka.routing.ActorPool
|
import akka.routing.ActorPool
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import akka.routing.{ ScatterGatherFirstCompletedRouter, BroadcastRouter, RandomRouter, RoundRobinRouter }
|
import akka.routing.{ ScatterGatherFirstCompletedRouter, BroadcastRouter, RandomRouter, RoundRobinRouter }
|
||||||
|
|
@ -21,7 +24,7 @@ class PrintlnActor extends Actor {
|
||||||
//#fibonacciActor
|
//#fibonacciActor
|
||||||
class FibonacciActor extends Actor {
|
class FibonacciActor extends Actor {
|
||||||
def receive = {
|
def receive = {
|
||||||
case FibonacciNumber(nbr) ⇒ sender.tell(fibonacci(nbr))
|
case FibonacciNumber(nbr) ⇒ sender tell fibonacci(nbr)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def fibonacci(n: Int): Int = {
|
private def fibonacci(n: Int): Int = {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import com.typesafe.config.{ ConfigFactory, Config }
|
|
||||||
import akka.actor.{ Actor, Props, ActorSystem }
|
import akka.actor.{ Actor, Props, ActorSystem }
|
||||||
import akka.routing.RoundRobinRouter
|
import akka.routing.RoundRobinRouter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2009-2011 Typesafe Inc. <http://www.typesafe.com>
|
||||||
|
*/
|
||||||
package akka.docs.routing
|
package akka.docs.routing
|
||||||
|
|
||||||
import akka.routing.RoundRobinRouter
|
import akka.routing.RoundRobinRouter
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
.. _routing-scala:
|
||||||
|
|
||||||
Routing (Scala)
|
Routing (Scala)
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
|
@ -39,7 +42,7 @@ and
|
||||||
Here is the configuration file to instruct the routers how many instances of routees to create::
|
Here is the configuration file to instruct the routers how many instances of routees to create::
|
||||||
|
|
||||||
akka.actor.deployment {
|
akka.actor.deployment {
|
||||||
/user/router {
|
/router {
|
||||||
nr-of-instances = 5
|
nr-of-instances = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +71,8 @@ When run you should see a similar output to this:
|
||||||
|
|
||||||
If you look closely to the output you can see that each of the routees received two messages which
|
If you look closely to the output you can see that each of the routees received two messages which
|
||||||
is exactly what you would expect from a round-robin router to happen.
|
is exactly what you would expect from a round-robin router to happen.
|
||||||
|
(The name of an actor is automatically created in the format ``$letter`` unless you specify it -
|
||||||
|
hence the names printed above.)
|
||||||
|
|
||||||
RandomRouter
|
RandomRouter
|
||||||
************
|
************
|
||||||
|
|
@ -164,7 +169,7 @@ Broadcast Messages
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
There is a special type of message that will be sent to all routees regardless of the router.
|
There is a special type of message that will be sent to all routees regardless of the router.
|
||||||
This message is called 'Broadcast' and is used in the following manner:
|
This message is called `Broadcast`` and is used in the following manner:
|
||||||
|
|
||||||
.. code-block:: scala
|
.. code-block:: scala
|
||||||
|
|
||||||
|
|
@ -234,7 +239,7 @@ The actor pool is built around three concepts: capacity, filtering and selection
|
||||||
Selection
|
Selection
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
All pools require a *Selector* to be mixed-in. This trait controls how and how many actors in the pool will
|
All pools require a ``Selector`` to be mixed-in. This trait controls how and how many actors in the pool will
|
||||||
receive the incoming message. Define *selectionCount* to some positive number greater than one to route to
|
receive the incoming message. Define *selectionCount* to some positive number greater than one to route to
|
||||||
multiple actors. Currently two are provided:
|
multiple actors. Currently two are provided:
|
||||||
|
|
||||||
|
|
@ -245,7 +250,7 @@ Partial Fills
|
||||||
*************
|
*************
|
||||||
|
|
||||||
When selecting more than one pooled actor, its possible that in order to fulfill the requested amount,
|
When selecting more than one pooled actor, its possible that in order to fulfill the requested amount,
|
||||||
the selection set must contain duplicates. By setting *partialFill* to **true**, you instruct the selector to
|
the selection set must contain duplicates. By setting ``partialFill`` to ``true``, you instruct the selector to
|
||||||
return only unique actors from the pool.
|
return only unique actors from the pool.
|
||||||
|
|
||||||
Capacity
|
Capacity
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue