!act,doc #3893 Removed isTerminated checks from ActorClassification
Instead of isTerminated we now use death watch on subscribers. ! Breaking change - ActorClassification based event buses now require and actor system. Previously no actors were involved, but now someone has to `watch` the subscribers. The unsubscriber is an system actor, and won't be stopped automagically if a bus stops to be used (hard to determine what "stops being used" is) * Replaced isTerminated checks with watching actors * backing structure for ActorClassification swaped from ConcurrentHashMap to immutable.Map with CAS operations on it. This is required to avoid races and guarantee register/unregister ordering (messages sent with proper sequence numbers) to the unsubscriber. Performance tested it and still above 1.3million subscribe+unsubscribe ops per second (mac i7, retina), where as the CHM version was 4 million - but that one could only work in the presence of itTerminated - so we pay the price here for removing it. * `ActorClassification` starts the unsubscriber instance by itself, the unsubscriber is an system actor, and can be stopped via `ActorClassification#shutdown` * Will unregister from unsubscriber, when no more subscriptions for given subscriber are left in this bus. * Added missing "Java API: " for some types * Updated docs to point out the automatic subscriber purging (on terminated)
This commit is contained in:
parent
f57470926e
commit
c046cdff0a
14 changed files with 471 additions and 157 deletions
|
|
@ -3,20 +3,27 @@
|
|||
*/
|
||||
package docs.event;
|
||||
|
||||
import akka.event.japi.EventBus;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import scala.concurrent.duration.FiniteDuration;
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.actor.ActorRef;
|
||||
import akka.event.japi.*;
|
||||
import akka.testkit.AkkaJUnitActorSystemResource;
|
||||
import akka.testkit.JavaTestKit;
|
||||
import akka.event.japi.EventBus;
|
||||
import akka.util.Subclassification;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import scala.concurrent.duration.FiniteDuration;
|
||||
|
||||
//#lookup-bus
|
||||
import akka.event.japi.LookupEventBus;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
//#lookup-bus
|
||||
|
||||
|
|
@ -226,6 +233,12 @@ public class EventBusDocTest {
|
|||
static
|
||||
//#actor-bus
|
||||
public class ActorBusImpl extends ActorEventBus<Notification> {
|
||||
|
||||
// the ActorSystem will be used for book-keeping operations, such as subscribers terminating
|
||||
public ActorBusImpl(ActorSystem system) {
|
||||
super(system);
|
||||
}
|
||||
|
||||
// is used for extracting the classifier from the incoming events
|
||||
@Override public ActorRef classify(Notification event) {
|
||||
return event.ref;
|
||||
|
|
@ -299,7 +312,7 @@ public class EventBusDocTest {
|
|||
JavaTestKit probe2 = new JavaTestKit(system);
|
||||
ActorRef subscriber1 = probe1.getRef();
|
||||
ActorRef subscriber2 = probe2.getRef();
|
||||
ActorBusImpl actorBus = new ActorBusImpl();
|
||||
ActorBusImpl actorBus = new ActorBusImpl(system);
|
||||
actorBus.subscribe(subscriber1, observer1);
|
||||
actorBus.subscribe(subscriber2, observer1);
|
||||
actorBus.subscribe(subscriber2, observer2);
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ A test for this implementation may look like this:
|
|||
This classifier takes always a time which is proportional to the number of
|
||||
subscriptions, independent of how many actually match.
|
||||
|
||||
.. _actor-classification-java:
|
||||
|
||||
Actor Classification
|
||||
--------------------
|
||||
|
||||
|
|
@ -111,6 +113,11 @@ This classification was originally developed specifically for implementing
|
|||
:ref:`DeathWatch <deathwatch-java>`: subscribers as well as classifiers are of
|
||||
type :class:`ActorRef`.
|
||||
|
||||
This classification requires an :class:`ActorSystem` in order to perform book-keeping
|
||||
operations related to the subscribers being Actors, which can terminate without first
|
||||
unsubscribing from the EventBus. ActorClassification maitains a system Actor which
|
||||
takes care of unsubscribing terminated actors automatically.
|
||||
|
||||
The necessary methods to be implemented are illustrated with the following example:
|
||||
|
||||
.. includecode:: code/docs/event/EventBusDocTest.java#actor-bus
|
||||
|
|
@ -141,6 +148,8 @@ it can be subscribed like this:
|
|||
|
||||
.. includecode:: code/docs/event/LoggingDocTest.java#deadletters
|
||||
|
||||
Similarily to `Actor Classification`_, :class:`EventStream` will automatically remove subscibers when they terminate.
|
||||
|
||||
.. note::
|
||||
The event stream is a *local facility*, meaning that it will *not* distribute events to other nodes in a clustered environment (unless you subscribe a Remote Actor to the stream explicitly).
|
||||
If you need to broadcast events in an Akka cluster, *without* knowing your recipients explicitly (i.e. obtaining their ActorRefs), you may want to look into: :ref:`distributed-pub-sub`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue