Merge pull request #1918 from akka/wip-2927-balancing-pool-patriknw

!act #2927 Add BalancingPool and deprecate BalancingDispatcher
This commit is contained in:
Patrik Nordwall 2014-01-16 12:30:26 -08:00
commit 32b76adb9a
26 changed files with 482 additions and 206 deletions

View file

@ -202,99 +202,111 @@ public class RouterDocTest {
ActorRef router8 =
getContext().actorOf(new RandomGroup(paths).props(), "router8");
//#random-group-2
//#smallest-mailbox-pool-1
//#balancing-pool-1
ActorRef router9 =
getContext().actorOf(FromConfig.getInstance().props(
Props.create(Worker.class)), "router9");
//#smallest-mailbox-pool-1
//#balancing-pool-1
//#smallest-mailbox-pool-2
//#balancing-pool-2
ActorRef router10 =
getContext().actorOf(new SmallestMailboxPool(5).props(
Props.create(Worker.class)), "router10");
//#smallest-mailbox-pool-2
//#balancing-pool-2
//#broadcast-pool-1
//#smallest-mailbox-pool-1
ActorRef router11 =
getContext().actorOf(FromConfig.getInstance().props(
Props.create(Worker.class)), "router11");
//#smallest-mailbox-pool-1
//#smallest-mailbox-pool-2
ActorRef router12 =
getContext().actorOf(new SmallestMailboxPool(5).props(
Props.create(Worker.class)), "router12");
//#smallest-mailbox-pool-2
//#broadcast-pool-1
ActorRef router13 =
getContext().actorOf(FromConfig.getInstance().props(
Props.create(Worker.class)), "router13");
//#broadcast-pool-1
//#broadcast-pool-2
ActorRef router12 =
ActorRef router14 =
getContext().actorOf(new BroadcastPool(5).props(Props.create(Worker.class)),
"router12");
"router14");
//#broadcast-pool-2
//#broadcast-group-1
ActorRef router13 =
getContext().actorOf(FromConfig.getInstance().props(), "router13");
ActorRef router15 =
getContext().actorOf(FromConfig.getInstance().props(), "router15");
//#broadcast-group-1
//#broadcast-group-2
ActorRef router14 =
getContext().actorOf(new BroadcastGroup(paths).props(), "router14");
ActorRef router16 =
getContext().actorOf(new BroadcastGroup(paths).props(), "router16");
//#broadcast-group-2
//#scatter-gather-pool-1
ActorRef router15 =
ActorRef router17 =
getContext().actorOf(FromConfig.getInstance().props(
Props.create(Worker.class)), "router15");
Props.create(Worker.class)), "router17");
//#scatter-gather-pool-1
//#scatter-gather-pool-2
FiniteDuration within = FiniteDuration.create(10, TimeUnit.SECONDS);
ActorRef router16 =
ActorRef router18 =
getContext().actorOf(new ScatterGatherFirstCompletedPool(5, within).props(
Props.create(Worker.class)), "router16");
Props.create(Worker.class)), "router18");
//#scatter-gather-pool-2
//#scatter-gather-group-1
ActorRef router17 =
getContext().actorOf(FromConfig.getInstance().props(), "router17");
ActorRef router19 =
getContext().actorOf(FromConfig.getInstance().props(), "router19");
//#scatter-gather-group-1
//#scatter-gather-group-2
FiniteDuration within2 = FiniteDuration.create(10, TimeUnit.SECONDS);
ActorRef router18 =
ActorRef router20 =
getContext().actorOf(new ScatterGatherFirstCompletedGroup(paths, within2).props(),
"router18");
"router20");
//#scatter-gather-group-2
//#consistent-hashing-pool-1
ActorRef router19 =
ActorRef router21 =
getContext().actorOf(FromConfig.getInstance().props(Props.create(Worker.class)),
"router19");
"router21");
//#consistent-hashing-pool-1
//#consistent-hashing-pool-2
ActorRef router20 =
ActorRef router22 =
getContext().actorOf(new ConsistentHashingPool(5).props(
Props.create(Worker.class)), "router20");
Props.create(Worker.class)), "router22");
//#consistent-hashing-pool-2
//#consistent-hashing-group-1
ActorRef router21 =
getContext().actorOf(FromConfig.getInstance().props(), "router21");
ActorRef router23 =
getContext().actorOf(FromConfig.getInstance().props(), "router23");
//#consistent-hashing-group-1
//#consistent-hashing-group-2
ActorRef router22 =
getContext().actorOf(new ConsistentHashingGroup(paths).props(), "router22");
ActorRef router24 =
getContext().actorOf(new ConsistentHashingGroup(paths).props(), "router24");
//#consistent-hashing-group-2
//#resize-pool-1
ActorRef router23 =
ActorRef router25 =
getContext().actorOf(FromConfig.getInstance().props(
Props.create(Worker.class)), "router23");
Props.create(Worker.class)), "router25");
//#resize-pool-1
//#resize-pool-2
DefaultResizer resizer = new DefaultResizer(2, 15);
ActorRef router24 =
ActorRef router26 =
getContext().actorOf(new RoundRobinPool(5).withResizer(resizer).props(
Props.create(Worker.class)), "router24");
Props.create(Worker.class)), "router26");
//#resize-pool-2
public void onReceive(Object msg) {}

View file

@ -87,27 +87,6 @@ There are 4 different types of message dispatchers:
- Driven by: Any ``akka.dispatch.ThreadPoolExecutorConfigurator``
by default a "thread-pool-executor"
* BalancingDispatcher
- This is an executor based event driven dispatcher that will try to redistribute work from busy actors to idle actors.
- All the actors share a single Mailbox that they get their messages from.
- It is assumed that all actors using the same instance of this dispatcher can process all messages that have been sent to one of the actors; i.e. the actors belong to a pool of actors, and to the client there is no guarantee about which actor instance actually processes a given message.
- Sharability: Actors of the same type only
- Mailboxes: Any, creates one for all Actors
- Use cases: Work-sharing
- Driven by: ``java.util.concurrent.ExecutorService``
specify using "executor" using "fork-join-executor",
"thread-pool-executor" or the FQCN of
an ``akka.dispatcher.ExecutorServiceConfigurator``
- Note that you can **not** use a ``BalancingDispatcher`` as a **Router Dispatcher**. (You can however use it for the **Routees**)
* CallingThreadDispatcher
- This dispatcher runs invocations on the current thread only. This dispatcher does not create any new threads,

View file

@ -4,8 +4,8 @@ Mailboxes
#########
An Akka ``Mailbox`` holds the messages that are destined for an ``Actor``.
Normally each ``Actor`` has its own mailbox, but with for example a ``BalancingDispatcher``
all actors with the same ``BalancingDispatcher`` will share a single instance.
Normally each ``Actor`` has its own mailbox, but with for example a ``BalancingPool``
all routees will share a single mailbox instance.
Mailbox Selection
=================

View file

@ -252,6 +252,31 @@ RandomGroup defined in code:
.. includecode:: code/docs/jrouting/RouterDocTest.java
:include: paths,random-group-2
.. _balancing-pool-java:
BalancingPool
-------------
A Router that will try to redistribute work from busy routees to idle routees.
All routees share the same mailbox.
BalancingPool defined in configuration:
.. includecode:: ../scala/code/docs/routing/RouterDocSpec.scala#config-balancing-pool
.. includecode:: code/docs/jrouting/RouterDocTest.java#balancing-pool-1
BalancingPool defined in code:
.. includecode:: code/docs/jrouting/RouterDocTest.java#balancing-pool-2
Addition configuration for the balancing dispatcher, which is used by the pool,
can be configured in the ``pool-dispatcher`` section of the router deployment
configuration.
.. includecode:: ../scala/code/docs/routing/RouterDocSpec.scala#config-balancing-pool2
There is no Group variant of the BalancingPool.
SmallestMailboxPool
-------------------
@ -628,11 +653,7 @@ Configuring Dispatchers
^^^^^^^^^^^^^^^^^^^^^^^
The dispatcher for created children of the pool will be taken from
``Props`` as described in :ref:`dispatchers-scala`. For a pool it
makes sense to configure the ``BalancingDispatcher`` if the precise
routing is not so important (i.e. no consistent hashing or round-robin is
required); this enables newly created routees to pick up work immediately by
stealing it from their siblings.
``Props`` as described in :ref:`dispatchers-scala`.
To make it easy to define the dispatcher of the routees of the pool you can
define the dispatcher inline in the deployment section of the config.
@ -642,7 +663,6 @@ define the dispatcher inline in the deployment section of the config.
That is the only thing you need to do enable a dedicated dispatcher for a
pool.
.. note::
If you use a group of actors and route to their paths, then they will still use the same dispatcher
@ -662,28 +682,6 @@ implement the method in a suitable way.
.. note::
It is not allowed to configure the ``routerDispatcher`` to be a
:class:`BalancingDispatcher` since the messages meant for the special
router actor cannot be processed by any other actor.
At first glance there seems to be an overlap between the
:class:`BalancingDispatcher` and Routers, but they complement each other.
The balancing dispatcher is in charge of running the actors while the routers
are in charge of deciding which message goes where. A router can also have
children that span multiple actor systems, even remote ones, but a dispatcher
lives inside a single actor system.
When using a :class:`RoundRobinRouter` with a :class:`BalancingDispatcher`
there are some configuration settings to take into account.
- There can only be ``nr-of-instances`` messages being processed at the same
time no matter how many threads are configured for the
:class:`BalancingDispatcher`.
- Having ``throughput`` set to a low number makes no sense since you will only
be handing off to another actor that processes the same :class:`MailBox`
as yourself, which can be costly. Either the message just got into the
mailbox and you can receive it as well as anybody else, or everybody else
is busy and you are the only one available to receive the message.
- Resizing the number of routees only introduce inertia, since resizing
is performed at specified intervals, but work stealing is instantaneous.
:class:`akka.dispatch.BalancingDispatcherConfigurator` since the messages meant
for the special router actor cannot be processed by any other actor.