DOC: Corrections of dispatcher docs from review. See #1471

This commit is contained in:
Patrik Nordwall 2011-12-13 14:29:10 +01:00
parent eede488fd3
commit 7a17eb00bf
7 changed files with 27 additions and 30 deletions

View file

@ -334,7 +334,7 @@ class TypedActorSpec extends AkkaSpec with BeforeAndAfterEach with BeforeAndAfte
mustStop(t) mustStop(t)
} }
"be able to use work-stealing dispatcher" in { "be able to use balancing dispatcher" in {
val props = Props( val props = Props(
timeout = Timeout(6600), timeout = Timeout(6600),
dispatcher = system.dispatcherFactory.newBalancingDispatcher("pooled-dispatcher") dispatcher = system.dispatcherFactory.newBalancingDispatcher("pooled-dispatcher")

View file

@ -116,7 +116,7 @@ akka {
task-queue-type = "linked" # Specifies which type of task queue will be used, can be "array" or "linked" (default) task-queue-type = "linked" # Specifies which type of task queue will be used, can be "array" or "linked" (default)
allow-core-timeout = on # Allow core threads to time out allow-core-timeout = on # Allow core threads to time out
throughput = 5 # Throughput defines the number of messages that are processed in a batch before the throughput = 5 # Throughput defines the number of messages that are processed in a batch before the
# thread is returned to the pool. Set to 1 for complete fairness. # thread is returned to the pool. Set to 1 for as fair as possible.
throughput-deadline-time = 0ms # Throughput deadline for Dispatcher, set to 0 or negative for no deadline throughput-deadline-time = 0ms # Throughput deadline for Dispatcher, set to 0 or negative for no deadline
mailbox-capacity = -1 # If negative (or zero) then an unbounded mailbox is used (default) mailbox-capacity = -1 # If negative (or zero) then an unbounded mailbox is used (default)
# If positive then a bounded mailbox is used and the capacity is set using the property # If positive then a bounded mailbox is used and the capacity is set using the property

View file

@ -74,6 +74,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
throw new ConfigurationException("Wrong configuration [akka.actor.default-dispatcher]") throw new ConfigurationException("Wrong configuration [akka.actor.default-dispatcher]")
} }
// FIXME: Dispatchers registered here are are not removed, see ticket #1494
private val dispatchers = new ConcurrentHashMap[String, MessageDispatcher] private val dispatchers = new ConcurrentHashMap[String, MessageDispatcher]
/** /**
@ -84,7 +85,9 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
def lookup(key: String): MessageDispatcher = { def lookup(key: String): MessageDispatcher = {
dispatchers.get(key) match { dispatchers.get(key) match {
case null case null
// doesn't matter if we create a dispatcher that isn't used due to concurrent lookup // It doesn't matter if we create a dispatcher that isn't used due to concurrent lookup.
// That shouldn't happen often and in case it does the actual ExecutorService isn't
// created until used, i.e. cheap.
val newDispatcher = newFromConfig(key) val newDispatcher = newFromConfig(key)
dispatchers.putIfAbsent(key, newDispatcher) match { dispatchers.putIfAbsent(key, newDispatcher) match {
case null newDispatcher case null newDispatcher
@ -161,7 +164,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
new Dispatcher(prerequisites, name, throughput, throughputDeadline, mailboxType, config, settings.DispatcherDefaultShutdown), ThreadPoolConfig()) new Dispatcher(prerequisites, name, throughput, throughputDeadline, mailboxType, config, settings.DispatcherDefaultShutdown), ThreadPoolConfig())
/** /**
* Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * Creates a executor-based event-driven dispatcher, with work-sharing, serving multiple (millions) of actors through a thread pool.
* <p/> * <p/>
* Has a fluent builder interface for configuring its semantics. * Has a fluent builder interface for configuring its semantics.
*/ */
@ -170,7 +173,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
settings.DispatcherThroughputDeadlineTime, MailboxType, config, settings.DispatcherDefaultShutdown), ThreadPoolConfig()) settings.DispatcherThroughputDeadlineTime, MailboxType, config, settings.DispatcherDefaultShutdown), ThreadPoolConfig())
/** /**
* Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * Creates a executor-based event-driven dispatcher, with work-sharing, serving multiple (millions) of actors through a thread pool.
* <p/> * <p/>
* Has a fluent builder interface for configuring its semantics. * Has a fluent builder interface for configuring its semantics.
*/ */
@ -180,7 +183,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
config, settings.DispatcherDefaultShutdown), ThreadPoolConfig()) config, settings.DispatcherDefaultShutdown), ThreadPoolConfig())
/** /**
* Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * Creates a executor-based event-driven dispatcher, with work-sharing, serving multiple (millions) of actors through a thread pool.
* <p/> * <p/>
* Has a fluent builder interface for configuring its semantics. * Has a fluent builder interface for configuring its semantics.
*/ */
@ -190,7 +193,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
config, settings.DispatcherDefaultShutdown), ThreadPoolConfig()) config, settings.DispatcherDefaultShutdown), ThreadPoolConfig())
/** /**
* Creates a executor-based event-driven dispatcher, with work-stealing, serving multiple (millions) of actors through a thread pool. * Creates a executor-based event-driven dispatcher, with work-sharing, serving multiple (millions) of actors through a thread pool.
* <p/> * <p/>
* Has a fluent builder interface for configuring its semantics. * Has a fluent builder interface for configuring its semantics.
*/ */

View file

@ -28,10 +28,10 @@ configuration for each actor system, and grab the specific configuration when in
:: ::
myapp1 { myapp1 {
akka.logLevel = WARNING akka.loglevel = WARNING
} }
myapp2 { myapp2 {
akka.logLevel = ERROR akka.loglevel = ERROR
} }
.. code-block:: scala .. code-block:: scala
@ -120,7 +120,7 @@ A custom ``application.conf`` might look like this::
actor { actor {
default-dispatcher { default-dispatcher {
throughput = 10 # Throughput for default Dispatcher, set to 1 for complete fairness throughput = 10 # Throughput for default Dispatcher, set to 1 for as fair as possible
} }
} }

View file

@ -14,7 +14,6 @@ import akka.actor.PoisonPill
object DispatcherDocSpec { object DispatcherDocSpec {
val config = """ val config = """
akka.logLevel=INFO
//#my-dispatcher-config //#my-dispatcher-config
my-dispatcher { my-dispatcher {
type = Dispatcher # Dispatcher is the name of the event-based dispatcher type = Dispatcher # Dispatcher is the name of the event-based dispatcher
@ -22,7 +21,7 @@ object DispatcherDocSpec {
core-pool-size-factor = 2.0 # No of core threads ... ceil(available processors * factor) core-pool-size-factor = 2.0 # No of core threads ... ceil(available processors * factor)
core-pool-size-max = 10 # maximum number of threads to cap factor-based number to core-pool-size-max = 10 # maximum number of threads to cap factor-based number to
throughput = 100 # Throughput defines the number of messages that are processed in a batch before the throughput = 100 # Throughput defines the number of messages that are processed in a batch before the
# thread is returned to the pool. Set to 1 for complete fairness. # thread is returned to the pool. Set to 1 for as fair as possible.
} }
//#my-dispatcher-config //#my-dispatcher-config

View file

@ -64,7 +64,8 @@ Let's now walk through the different dispatchers in more detail.
Thread-based Thread-based
^^^^^^^^^^^^ ^^^^^^^^^^^^
The ``PinnedDispatcher`` binds a dedicated OS thread to each specific Actor. The messages are posted to a ``LinkedBlockingQueue`` The ``PinnedDispatcher`` binds a dedicated OS thread to each specific Actor. The messages are posted to a
`LinkedBlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html>`_
which feeds the messages to the dispatcher one by one. A ``PinnedDispatcher`` cannot be shared between actors. This dispatcher which feeds the messages to the dispatcher one by one. A ``PinnedDispatcher`` cannot be shared between actors. This dispatcher
has worse performance and scalability than the event-based dispatcher but works great for creating "daemon" Actors that consumes has worse performance and scalability than the event-based dispatcher but works great for creating "daemon" Actors that consumes
a low frequency of messages and are allowed to go off and do their own thing for a longer period of time. Another advantage with a low frequency of messages and are allowed to go off and do their own thing for a longer period of time. Another advantage with
@ -79,7 +80,8 @@ The ``PinnedDispatcher`` is configured as a event-based dispatcher with with cor
Event-based Event-based
^^^^^^^^^^^ ^^^^^^^^^^^
The event-based ``Dispatcher`` binds a set of Actors to a thread pool backed up by a ``BlockingQueue``. This dispatcher is highly configurable The event-based ``Dispatcher`` binds a set of Actors to a thread pool backed up by a
`BlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html>`_. This dispatcher is highly configurable
and supports a fluent configuration API to configure the ``BlockingQueue`` (type of queue, max items etc.) as well as the thread pool. and supports a fluent configuration API to configure the ``BlockingQueue`` (type of queue, max items etc.) as well as the thread pool.
The event-driven dispatchers **must be shared** between multiple Actors. One best practice is to let each top-level Actor, e.g. The event-driven dispatchers **must be shared** between multiple Actors. One best practice is to let each top-level Actor, e.g.
@ -90,21 +92,14 @@ design and implement your system in the most efficient way in regards to perform
It comes with many different predefined BlockingQueue configurations: It comes with many different predefined BlockingQueue configurations:
* Bounded LinkedBlockingQueue * Bounded `LinkedBlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html>`_
* Unbounded LinkedBlockingQueue * Unbounded `LinkedBlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html>`_
* Bounded ArrayBlockingQueue * Bounded `ArrayBlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html>`_
* Unbounded ArrayBlockingQueue * Unbounded `ArrayBlockingQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html>`_
* SynchronousQueue * `SynchronousQueue <http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue.html>`_
You can also set the rejection policy that should be used, e.g. what should be done if the dispatcher (e.g. the Actor) can't keep up When using a bounded queue and it has grown up to limit defined the message processing will run in the caller's
and the mailbox is growing up to the limit defined. You can choose between four different rejection policies: thread as a way to slow him down and balance producer/consumer.
* java.util.concurrent.ThreadPoolExecutor.CallerRuns - will run the message processing in the caller's thread as a way to slow him down and balance producer/consumer
* java.util.concurrent.ThreadPoolExecutor.AbortPolicy - rejected messages by throwing a ``RejectedExecutionException``
* java.util.concurrent.ThreadPoolExecutor.DiscardPolicy - discards the message (throws it away)
* java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy - discards the oldest message in the mailbox (throws it away)
You can read more about these policies `here <http://java.sun.com/javase/6/docs/api/index.html?java/util/concurrent/RejectedExecutionHandler.html>`_.
Here is an example of a bounded mailbox: Here is an example of a bounded mailbox:
@ -113,7 +108,7 @@ Here is an example of a bounded mailbox:
The standard :class:`Dispatcher` allows you to define the ``throughput`` it The standard :class:`Dispatcher` allows you to define the ``throughput`` it
should have, as shown above. This defines the number of messages for a specific should have, as shown above. This defines the number of messages for a specific
Actor the dispatcher should process in one single sweep; in other words, the Actor the dispatcher should process in one single sweep; in other words, the
dispatcher will bunch up to ``throughput`` messages together when dispatcher will batch process up to ``throughput`` messages together when
having elected an actor to run. Setting this to a higher number will increase having elected an actor to run. Setting this to a higher number will increase
throughput but lower fairness, and vice versa. If you don't specify it explicitly throughput but lower fairness, and vice versa. If you don't specify it explicitly
then it uses the value (5) defined for ``default-dispatcher`` in the :ref:`configuration`. then it uses the value (5) defined for ``default-dispatcher`` in the :ref:`configuration`.

View file

@ -11,7 +11,7 @@ The Typed Actors are implemented through `Typed Actors <http://en.wikipedia.org/
If you are using the `Spring Framework <http://springsource.org>`_ then take a look at Akka's `Spring integration <spring-integration>`_. If you are using the `Spring Framework <http://springsource.org>`_ then take a look at Akka's `Spring integration <spring-integration>`_.
**WARNING:** Do not configure to use a ``WorkStealingDispatcher`` with your ``TypedActors``, it just isn't safe with how ``TypedActors`` currently are implemented. This limitation will most likely be removed in the future. **WARNING:** Do not configure to use a ``BalancingDispatcher`` with your ``TypedActors``, it just isn't safe with how ``TypedActors`` currently are implemented. This limitation will most likely be removed in the future.
Creating Typed Actors Creating Typed Actors
--------------------- ---------------------