DOC: Corrections of dispatcher docs from review. See #1471
This commit is contained in:
parent
eede488fd3
commit
7a17eb00bf
7 changed files with 27 additions and 30 deletions
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue