incorporate review comments, add docs, see #2031
also add Java sample for creating custom MailboxType
This commit is contained in:
parent
b60210362e
commit
422cf386c8
12 changed files with 157 additions and 60 deletions
|
|
@ -24,6 +24,15 @@ import com.typesafe.config.Config;
|
|||
|
||||
//#imports-prio-mailbox
|
||||
|
||||
//#imports-custom
|
||||
import akka.dispatch.Envelope;
|
||||
import akka.dispatch.MessageQueue;
|
||||
import akka.dispatch.MailboxType;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
//#imports-custom
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -136,4 +145,32 @@ public class DispatcherDocTestBase {
|
|||
}
|
||||
}
|
||||
//#prio-mailbox
|
||||
|
||||
//#mailbox-implementation-example
|
||||
class MyUnboundedMailbox implements MailboxType {
|
||||
|
||||
// This constructor signature must exist, it will be called by Akka
|
||||
public MyUnboundedMailbox(ActorSystem.Settings settings, Config config) {
|
||||
// put your initialization code here
|
||||
}
|
||||
|
||||
// The create method is called to create the MessageQueue
|
||||
public MessageQueue create(Option<ActorRef> owner, Option<ActorSystem> system) {
|
||||
return new MessageQueue() {
|
||||
private final Queue<Envelope> queue = new ConcurrentLinkedQueue<Envelope>();
|
||||
|
||||
// these must be implemented; queue used as example
|
||||
public void enqueue(ActorRef receiver, Envelope handle) { queue.offer(handle); }
|
||||
public Envelope dequeue() { return queue.poll(); }
|
||||
public int numberOfMessages() { return queue.size(); }
|
||||
public boolean hasMessages() { return !queue.isEmpty(); }
|
||||
public void cleanUp(ActorRef owner, MessageQueue deadLetters) {
|
||||
for (Envelope handle: queue) {
|
||||
deadLetters.enqueue(owner, handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
//#mailbox-implementation-example
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,3 +183,44 @@ And then an example on how you would use it:
|
|||
the configuration which describes the dispatcher using this mailbox type; the
|
||||
mailbox type will be instantiated once for each dispatcher using it.
|
||||
|
||||
Creating your own Mailbox type
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An example is worth a thousand quacks:
|
||||
|
||||
.. includecode:: code/docs/dispatcher/DispatcherDocTestBase.java#imports-custom
|
||||
|
||||
.. 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.
|
||||
|
||||
.. 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.
|
||||
|
||||
|
||||
Special Semantics of ``system.actorOf``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to make ``system.actorOf`` both synchronous and non-blocking while
|
||||
keeping the return type :class:`ActorRef` (and the semantics that the returned
|
||||
ref is fully functional), special handling takes place for this case. Behind
|
||||
the scenes, a hollow kind of actor reference is constructed, which is sent to
|
||||
the system’s guardian actor who actually creates the actor and its context and
|
||||
puts those inside the reference. Until that has happened, messages sent to the
|
||||
:class:`ActorRef` will be queued locally, and only upon swapping the real
|
||||
filling in will they be transferred into the real mailbox. Thus,
|
||||
|
||||
.. code-block:: scala
|
||||
|
||||
system.actorOf(...).tell("bang");
|
||||
assert(bangIsInMyCustomMailbx);
|
||||
|
||||
will probably fail; you will have to allow for some time to pass and retry the
|
||||
check à la :meth:`TestKit.awaitCond`.
|
||||
|
||||
|
|
|
|||
|
|
@ -82,13 +82,6 @@ that is used in log messages and for identifying actors. The name must not be em
|
|||
or start with ``$``. If the given name is already in use by another child to the
|
||||
same parent actor an `InvalidActorNameException` is thrown.
|
||||
|
||||
.. warning::
|
||||
|
||||
Creating top-level actors with ``system.actorOf`` is a blocking operation,
|
||||
hence it may dead-lock due to starvation if the default dispatcher is
|
||||
overloaded. To avoid problems, do not call this method from within actors or
|
||||
futures which run on the default dispatcher.
|
||||
|
||||
Actors are automatically started asynchronously when created.
|
||||
When you create the ``UntypedActor`` then it will automatically call the ``preStart``
|
||||
callback method on the ``UntypedActor`` class. This is an excellent place to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue