Allow different types of mailboxes on the same dispatcher. See #2687
This commit is contained in:
parent
c86cc0b8f7
commit
c3eed374f1
32 changed files with 735 additions and 74 deletions
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.actor;
|
||||
|
||||
//#my-bounded-untyped-actor
|
||||
import akka.dispatch.BoundedMessageQueueSemantics;
|
||||
import akka.dispatch.RequiresMessageQueue;
|
||||
|
||||
public class MyBoundedUntypedActor extends MyUntypedActor
|
||||
implements RequiresMessageQueue<BoundedMessageQueueSemantics> {
|
||||
}
|
||||
//#my-bounded-untyped-actor
|
||||
|
|
@ -30,6 +30,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
|
||||
//#imports-custom
|
||||
|
||||
//#imports-required-mailbox
|
||||
|
||||
//#imports-required-mailbox
|
||||
|
||||
import docs.actor.MyBoundedUntypedActor;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
|
@ -48,8 +53,8 @@ public class DispatcherDocTestBase {
|
|||
@BeforeClass
|
||||
public static void beforeAll() {
|
||||
system = ActorSystem.create("MySystem",
|
||||
ConfigFactory.parseString(
|
||||
DispatcherDocSpec.config()).withFallback(AkkaSpec.testConf()));
|
||||
ConfigFactory.parseString(DispatcherDocSpec.javaConfig()).withFallback(
|
||||
ConfigFactory.parseString(DispatcherDocSpec.config())).withFallback(AkkaSpec.testConf()));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
@ -96,6 +101,33 @@ public class DispatcherDocTestBase {
|
|||
//#lookup
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void defineMailboxInConfig() {
|
||||
//#defining-mailbox-in-config
|
||||
ActorRef myActor =
|
||||
system.actorOf(Props.create(MyUntypedActor.class),
|
||||
"priomailboxactor");
|
||||
//#defining-mailbox-in-config
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void defineMailboxInCode() {
|
||||
//#defining-mailbox-in-code
|
||||
ActorRef myActor =
|
||||
system.actorOf(Props.create(MyUntypedActor.class)
|
||||
.withMailbox("prio-mailbox"));
|
||||
//#defining-mailbox-in-code
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void usingARequiredMailbox() {
|
||||
ActorRef myActor =
|
||||
system.actorOf(Props.create(MyBoundedUntypedActor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void priorityDispatcher() throws Exception {
|
||||
JavaTestKit probe = new JavaTestKit(system);
|
||||
|
|
|
|||
|
|
@ -202,14 +202,55 @@ And then an example on how you would use it:
|
|||
|
||||
.. includecode:: ../java/code/docs/dispatcher/DispatcherDocTestBase.java#prio-dispatcher
|
||||
|
||||
It is also possible to configure a mailbox type directly like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: prio-mailbox-config-java,mailbox-deployment-config
|
||||
|
||||
And then use it either from deployment like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTestBase.java#defining-mailbox-in-config
|
||||
|
||||
Or code like this:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTestBase.java#defining-mailbox-in-code
|
||||
|
||||
|
||||
Requiring a message queue type for an Actor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It is possible to require a certain type of message queue for a certain type of actor
|
||||
by having that actor implement the parameterized interface :class:`RequiresMessageQueue`. Here is
|
||||
an example:
|
||||
|
||||
.. includecode:: code/docs/actor/MyBoundedUntypedActor.java#my-bounded-untyped-actor
|
||||
|
||||
The type parameter to the :class:`RequiresMessageQueue` interface needs to be mapped to a mailbox in
|
||||
configuration like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: bounded-mailbox-config,required-mailbox-config
|
||||
|
||||
Now every time you create an actor of type :class:`MyBoundedUntypedActor` it will try to get a bounded
|
||||
mailbox. If the actor has a different mailbox configured in deployment, either directly or via
|
||||
a dispatcher with a specified mailbox type, then that will override this mapping.
|
||||
|
||||
.. note::
|
||||
|
||||
Make sure to include a constructor which takes
|
||||
``akka.actor.ActorSystem.Settings`` and ``com.typesafe.config.Config``
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher using this mailbox type; the
|
||||
mailbox type will be instantiated once for each dispatcher using it.
|
||||
The type of the queue in the mailbox created for an actor will be checked against the required type in the
|
||||
interface and if the queue doesn't implement the required type an error will be logged.
|
||||
|
||||
|
||||
Mailbox configuration precedence
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The order of precedence for the mailbox type of an actor, where lower numbers override higher, is:
|
||||
|
||||
1. Mailbox type configured in the deployment of the actor
|
||||
2. Mailbox type configured on the dispatcher of the actor
|
||||
3. Mailbox type configured on the Props of the actor
|
||||
4. Mailbox type configured via message queue requirement
|
||||
|
||||
|
||||
Creating your own Mailbox type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -220,7 +261,8 @@ An example is worth a thousand quacks:
|
|||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTestBase.java#mailbox-implementation-example
|
||||
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher configuration.
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -228,8 +270,9 @@ And then you just specify the FQCN of your MailboxType as the value of the "mail
|
|||
``akka.actor.ActorSystem.Settings`` and ``com.typesafe.config.Config``
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher using this mailbox type; the
|
||||
mailbox type will be instantiated once for each dispatcher using it.
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
|
||||
Special Semantics of ``system.actorOf``
|
||||
|
|
|
|||
|
|
@ -245,12 +245,13 @@ directives are part of the :class:`Act` trait):
|
|||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#supervise-with
|
||||
|
||||
|
||||
Last but not least there is a little bit of convenience magic built-in, which
|
||||
detects if the runtime class of the statically given actor subtype extends the
|
||||
:class:`Stash` trait (this is a complicated way of saying that ``new Act with
|
||||
Stash`` would not work because its runtime erased type is just an anonymous
|
||||
subtype of ``Act``). The purpose is to automatically use a dispatcher with the
|
||||
appropriate deque-based mailbox, ``akka.actor.default-stash-dispatcher``.
|
||||
:class:`RequiresMessageQueue` trait via the :class:`Stash` trait (this is a
|
||||
complicated way of saying that ``new Act with Stash`` would not work because its
|
||||
runtime erased type is just an anonymous subtype of ``Act``). The purpose is to
|
||||
automatically use the appropriate deque-based mailbox type required by :class:`Stash`.
|
||||
If you want to use this magic, simply extend :class:`ActWithStash`:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#act-with-stash
|
||||
|
|
|
|||
|
|
@ -12,8 +12,25 @@ import akka.event.Logging
|
|||
import akka.event.LoggingAdapter
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor._
|
||||
import docs.dispatcher.DispatcherDocSpec.MyBoundedActor
|
||||
|
||||
object DispatcherDocSpec {
|
||||
val javaConfig = """
|
||||
//#prio-dispatcher-config-java
|
||||
prio-dispatcher {
|
||||
mailbox-type = "docs.dispatcher.DispatcherDocTestBase$MyPrioMailbox"
|
||||
//Other dispatcher configuration goes here
|
||||
}
|
||||
//#prio-dispatcher-config-java
|
||||
|
||||
//#prio-mailbox-config-java
|
||||
prio-mailbox {
|
||||
mailbox-type = "docs.dispatcher.DispatcherDocSpec$MyPrioMailbox"
|
||||
//Other mailbox configuration goes here
|
||||
}
|
||||
//#prio-mailbox-config-java
|
||||
"""
|
||||
|
||||
val config = """
|
||||
//#my-dispatcher-config
|
||||
my-dispatcher {
|
||||
|
|
@ -74,7 +91,7 @@ object DispatcherDocSpec {
|
|||
core-pool-size-factor = 8.0
|
||||
max-pool-size-factor = 16.0
|
||||
}
|
||||
# Specifies the bounded capacity of the mailbox queue
|
||||
# Specifies the bounded capacity of the message queue
|
||||
mailbox-capacity = 100
|
||||
throughput = 3
|
||||
}
|
||||
|
|
@ -94,15 +111,9 @@ object DispatcherDocSpec {
|
|||
//#prio-dispatcher-config
|
||||
prio-dispatcher {
|
||||
mailbox-type = "docs.dispatcher.DispatcherDocSpec$MyPrioMailbox"
|
||||
}
|
||||
//#prio-dispatcher-config
|
||||
|
||||
//#prio-dispatcher-config-java
|
||||
prio-dispatcher-java {
|
||||
mailbox-type = "docs.dispatcher.DispatcherDocTestBase$MyPrioMailbox"
|
||||
//Other dispatcher configuration goes here
|
||||
}
|
||||
//#prio-dispatcher-config-java
|
||||
//#prio-dispatcher-config
|
||||
|
||||
//#dispatcher-deployment-config
|
||||
akka.actor.deployment {
|
||||
|
|
@ -111,6 +122,38 @@ object DispatcherDocSpec {
|
|||
}
|
||||
}
|
||||
//#dispatcher-deployment-config
|
||||
|
||||
//#prio-mailbox-config
|
||||
prio-mailbox {
|
||||
mailbox-type = "docs.dispatcher.DispatcherDocSpec$MyPrioMailbox"
|
||||
//Other mailbox configuration goes here
|
||||
}
|
||||
//#prio-mailbox-config
|
||||
|
||||
//#mailbox-deployment-config
|
||||
|
||||
akka.actor.deployment {
|
||||
/priomailboxactor {
|
||||
mailbox = prio-mailbox
|
||||
}
|
||||
}
|
||||
//#mailbox-deployment-config
|
||||
|
||||
//#bounded-mailbox-config
|
||||
bounded-mailbox {
|
||||
mailbox-type = "akka.dispatch.BoundedMailbox"
|
||||
mailbox-capacity = 1000
|
||||
mailbox-push-timeout-time = 10s
|
||||
}
|
||||
//#bounded-mailbox-config
|
||||
|
||||
//#required-mailbox-config
|
||||
|
||||
akka.actor.mailbox.requirements {
|
||||
"akka.dispatch.BoundedMessageQueueSemantics" = bounded-mailbox
|
||||
}
|
||||
//#required-mailbox-config
|
||||
|
||||
"""
|
||||
|
||||
//#prio-mailbox
|
||||
|
|
@ -144,6 +187,13 @@ object DispatcherDocSpec {
|
|||
}
|
||||
}
|
||||
|
||||
//#required-mailbox-class
|
||||
import akka.dispatch.RequiresMessageQueue
|
||||
import akka.dispatch.BoundedMessageQueueSemantics
|
||||
|
||||
class MyBoundedActor extends MyActor with RequiresMessageQueue[BoundedMessageQueueSemantics]
|
||||
//#required-mailbox-class
|
||||
|
||||
//#mailbox-implementation-example
|
||||
class MyUnboundedMailbox extends akka.dispatch.MailboxType {
|
||||
import akka.actor.{ ActorRef, ActorSystem }
|
||||
|
|
@ -209,6 +259,27 @@ class DispatcherDocSpec extends AkkaSpec(DispatcherDocSpec.config) {
|
|||
//#lookup
|
||||
}
|
||||
|
||||
"defining mailbox in config" in {
|
||||
val context = system
|
||||
//#defining-mailbox-in-config
|
||||
import akka.actor.Props
|
||||
val myActor = context.actorOf(Props[MyActor], "priomailboxactor")
|
||||
//#defining-mailbox-in-config
|
||||
}
|
||||
|
||||
"defining mailbox in code" in {
|
||||
val context = system
|
||||
//#defining-mailbox-in-code
|
||||
import akka.actor.Props
|
||||
val myActor = context.actorOf(Props[MyActor].withMailbox("prio-mailbox"))
|
||||
//#defining-mailbox-in-code
|
||||
}
|
||||
|
||||
"using a required mailbox" in {
|
||||
val context = system
|
||||
val myActor = context.actorOf(Props[MyBoundedActor])
|
||||
}
|
||||
|
||||
"defining priority dispatcher" in {
|
||||
new AnyRef {
|
||||
//#prio-dispatcher
|
||||
|
|
|
|||
|
|
@ -204,6 +204,56 @@ And then an example on how you would use it:
|
|||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#prio-dispatcher
|
||||
|
||||
It is also possible to configure a mailbox type directly like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: prio-mailbox-config,mailbox-deployment-config
|
||||
|
||||
And then use it either from deployment like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#defining-mailbox-in-config
|
||||
|
||||
Or code like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#defining-mailbox-in-code
|
||||
|
||||
|
||||
Requiring a message queue type for an Actor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
It is possible to require a certain type of message queue for a certain type of actor
|
||||
by having that actor extend the parameterized trait :class:`RequiresMessageQueue`. Here is
|
||||
an example:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#required-mailbox-class
|
||||
|
||||
The type parameter to the :class:`RequiresMessageQueue` trait needs to be mapped to a mailbox in
|
||||
configuration like this:
|
||||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala
|
||||
:include: bounded-mailbox-config,required-mailbox-config
|
||||
|
||||
Now every time you create an actor of type :class:`MyBoundedActor` it will try to get a bounded
|
||||
mailbox. If the actor has a different mailbox configured in deployment, either directly or via
|
||||
a dispatcher with a specified mailbox type, then that will override this mapping.
|
||||
|
||||
.. note::
|
||||
|
||||
The type of the queue in the mailbox created for an actor will be checked against the required type in the
|
||||
trait and if the queue doesn't implement the required type an error will be logged.
|
||||
|
||||
|
||||
Mailbox configuration precedence
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The order of precedence for the mailbox type of an actor, where lower numbers override higher, is:
|
||||
|
||||
1. Mailbox type configured in the deployment of the actor
|
||||
2. Mailbox type configured on the dispatcher of the actor
|
||||
3. Mailbox type configured on the Props of the actor
|
||||
4. Mailbox type configured via message queue requirement
|
||||
|
||||
|
||||
Creating your own Mailbox type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
@ -211,7 +261,8 @@ An example is worth a thousand quacks:
|
|||
|
||||
.. includecode:: ../scala/code/docs/dispatcher/DispatcherDocSpec.scala#mailbox-implementation-example
|
||||
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher configuration.
|
||||
And then you just specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -219,8 +270,10 @@ And then you just specify the FQCN of your MailboxType as the value of the "mail
|
|||
``akka.actor.ActorSystem.Settings`` and ``com.typesafe.config.Config``
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher using this mailbox type; the
|
||||
mailbox type will be instantiated once for each dispatcher using it.
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
|
||||
Special Semantics of ``system.actorOf``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue