2011-12-30 00:00:25 +01:00
|
|
|
.. _event-bus-java:
|
|
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
###########
|
|
|
|
|
Event Bus
|
|
|
|
|
###########
|
|
|
|
|
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
Originally conceived as a way to send messages to groups of actors, the
|
2014-02-06 15:08:51 +01:00
|
|
|
:class:`EventBus` has been generalized into a set of abstract base classes
|
2011-12-30 00:00:25 +01:00
|
|
|
implementing a simple interface:
|
|
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#event-bus-api
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2013-07-02 12:11:50 +02:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
|
|
Please note that the EventBus does not preserve the sender of the
|
|
|
|
|
published messages. If you need a reference to the original sender
|
|
|
|
|
you have to provide it inside the message.
|
|
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
This mechanism is used in different places within Akka, e.g. the `Event Stream`_.
|
|
|
|
|
Implementations can make use of the specific building blocks presented below.
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
An event bus must define the following three type parameters:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
- :class:`Event` (E) is the type of all events published on that bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
- :class:`Subscriber` (S) is the type of subscribers allowed to register on that
|
|
|
|
|
event bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
- :class:`Classifier` (C) defines the classifier to be used in selecting
|
|
|
|
|
subscribers for dispatching events
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
The traits below are still generic in these types, but they need to be defined
|
|
|
|
|
for any concrete implementation.
|
|
|
|
|
|
|
|
|
|
Classifiers
|
|
|
|
|
===========
|
|
|
|
|
|
|
|
|
|
The classifiers presented here are part of the Akka distribution, but rolling
|
|
|
|
|
your own in case you do not find a perfect match is not difficult, check the
|
2014-02-06 15:08:51 +01:00
|
|
|
implementation of the existing ones on `github <@github@/akka-actor/src/main/scala/akka/event/EventBus.scala>`_
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
Lookup Classification
|
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
|
|
The simplest classification is just to extract an arbitrary classifier from
|
|
|
|
|
each event and maintaining a set of subscribers for each possible classifier.
|
2014-02-06 15:08:51 +01:00
|
|
|
This can be compared to tuning in on a radio station. The trait
|
|
|
|
|
:class:`LookupClassification` is still generic in that it abstracts over how to
|
|
|
|
|
compare subscribers and how exactly to classify.
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
The necessary methods to be implemented are illustrated with the following example:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#lookup-bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
A test for this implementation may look like this:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#lookup-bus-test
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
This classifier is efficient in case no subscribers exist for a particular event.
|
|
|
|
|
|
|
|
|
|
Subchannel Classification
|
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
|
|
If classifiers form a hierarchy and it is desired that subscription be possible
|
|
|
|
|
not only at the leaf nodes, this classification may be just the right one. It
|
|
|
|
|
can be compared to tuning in on (possibly multiple) radio channels by genre.
|
|
|
|
|
This classification has been developed for the case where the classifier is
|
|
|
|
|
just the JVM class of the event and subscribers may be interested in
|
|
|
|
|
subscribing to all subclasses of a certain class, but it may be used with any
|
2014-02-06 15:08:51 +01:00
|
|
|
classifier hierarchy.
|
|
|
|
|
|
|
|
|
|
The necessary methods to be implemented are illustrated with the following example:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#subchannel-bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
A test for this implementation may look like this:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#subchannel-bus-test
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
This classifier is also efficient in case no subscribers are found for an
|
|
|
|
|
event, but it uses conventional locking to synchronize an internal classifier
|
|
|
|
|
cache, hence it is not well-suited to use cases in which subscriptions change
|
|
|
|
|
with very high frequency (keep in mind that “opening” a classifier by sending
|
|
|
|
|
the first message will also have to re-check all previous subscriptions).
|
|
|
|
|
|
|
|
|
|
Scanning Classification
|
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
|
|
The previous classifier was built for multi-classifier subscriptions which are
|
|
|
|
|
strictly hierarchical, this classifier is useful if there are overlapping
|
|
|
|
|
classifiers which cover various parts of the event space without forming a
|
|
|
|
|
hierarchy. It can be compared to tuning in on (possibly multiple) radio
|
|
|
|
|
stations by geographical reachability (for old-school radio-wave transmission).
|
|
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
The necessary methods to be implemented are illustrated with the following example:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#scanning-bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
A test for this implementation may look like this:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#scanning-bus-test
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
This classifier takes always a time which is proportional to the number of
|
|
|
|
|
subscriptions, independent of how many actually match.
|
|
|
|
|
|
|
|
|
|
Actor Classification
|
|
|
|
|
--------------------
|
|
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
This classification was originally developed specifically for implementing
|
2011-12-30 00:00:25 +01:00
|
|
|
:ref:`DeathWatch <deathwatch-java>`: subscribers as well as classifiers are of
|
2014-02-06 15:08:51 +01:00
|
|
|
type :class:`ActorRef`.
|
|
|
|
|
|
|
|
|
|
The necessary methods to be implemented are illustrated with the following example:
|
|
|
|
|
|
|
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#actor-bus
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
A test for this implementation may look like this:
|
2011-12-30 00:00:25 +01:00
|
|
|
|
2014-02-06 15:08:51 +01:00
|
|
|
.. includecode:: code/docs/event/EventBusDocTest.java#actor-bus-test
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
This classifier is still is generic in the event type, and it is efficient for
|
|
|
|
|
all use cases.
|
|
|
|
|
|
|
|
|
|
.. _event-stream-java:
|
|
|
|
|
|
|
|
|
|
Event Stream
|
|
|
|
|
============
|
|
|
|
|
|
|
|
|
|
The event stream is the main event bus of each actor system: it is used for
|
|
|
|
|
carrying :ref:`log messages <logging-java>` and `Dead Letters`_ and may be
|
|
|
|
|
used by the user code for other purposes as well. It uses `Subchannel
|
|
|
|
|
Classification`_ which enables registering to related sets of channels (as is
|
2014-02-06 15:08:51 +01:00
|
|
|
used for :class:`RemotingLifecycleEvent`). The following example demonstrates
|
2011-12-30 00:00:25 +01:00
|
|
|
how a simple subscription works. Given a simple actor:
|
|
|
|
|
|
2013-05-08 09:42:25 +02:00
|
|
|
.. includecode:: code/docs/event/LoggingDocTest.java#imports-deadletter
|
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTest.java#deadletter-actor
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
it can be subscribed like this:
|
|
|
|
|
|
2013-05-08 09:42:25 +02:00
|
|
|
.. includecode:: code/docs/event/LoggingDocTest.java#deadletters
|
2011-12-30 00:00:25 +01:00
|
|
|
|
|
|
|
|
Default Handlers
|
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
Upon start-up the actor system creates and subscribes actors to the event
|
|
|
|
|
stream for logging: these are the handlers which are configured for example in
|
|
|
|
|
``application.conf``:
|
|
|
|
|
|
|
|
|
|
.. code-block:: text
|
|
|
|
|
|
|
|
|
|
akka {
|
2013-02-01 08:02:53 +01:00
|
|
|
loggers = ["akka.event.Logging$DefaultLogger"]
|
2011-12-30 00:00:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The handlers listed here by fully-qualified class name will be subscribed to
|
|
|
|
|
all log event classes with priority higher than or equal to the configured
|
|
|
|
|
log-level and their subscriptions are kept in sync when changing the log-level
|
|
|
|
|
at runtime::
|
|
|
|
|
|
|
|
|
|
system.eventStream.setLogLevel(Logging.DebugLevel());
|
|
|
|
|
|
2012-11-20 17:53:59 +01:00
|
|
|
This means that log events for a level which will not be logged are
|
2011-12-30 00:00:25 +01:00
|
|
|
typically not dispatched at all (unless manual subscriptions to the respective
|
|
|
|
|
event class have been done)
|
|
|
|
|
|
|
|
|
|
Dead Letters
|
|
|
|
|
------------
|
|
|
|
|
|
|
|
|
|
As described at :ref:`stopping-actors-java`, messages queued when an actor
|
|
|
|
|
terminates or sent after its death are re-routed to the dead letter mailbox,
|
|
|
|
|
which by default will publish the messages wrapped in :class:`DeadLetter`. This
|
|
|
|
|
wrapper holds the original sender, receiver and message of the envelope which
|
|
|
|
|
was redirected.
|
|
|
|
|
|
|
|
|
|
Other Uses
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
|
|
The event stream is always there and ready to be used, just publish your own
|
|
|
|
|
events (it accepts ``Object``) and subscribe listeners to the corresponding JVM
|
|
|
|
|
classes.
|
|
|
|
|
|