Skip to content

Commit

Permalink
docs: event stream document without typed case (akka#29109)
Browse files Browse the repository at this point in the history
  • Loading branch information
Roiocam committed Sep 14, 2023
1 parent 687bfa4 commit e52582f
Show file tree
Hide file tree
Showing 3 changed files with 342 additions and 65 deletions.
88 changes: 23 additions & 65 deletions akka-docs/src/main/paradox/event-bus.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,32 @@
# Classic Event Bus

Originally conceived as a way to send messages to groups of actors, the
@scala[@scaladoc[EventBus](akka.event.EventBus)]@java[@javadoc[EventBus](akka.event.japi.EventBus)] has been generalized into a set of @scala[composable traits] @java[abstract base classes]
implementing a simple interface:
@@include[includes.md](includes.md) { #actor-api }
For the full documentation of this feature and for new projects see @ref:[Event Bus](typed/event-bus.md).

Scala
: @@snip [EventBus.scala](/akka-actor/src/main/scala/akka/event/EventBus.scala) { #event-bus-api }
## Dependency

Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #event-bus-api }
@@include[typed/event-bus.md](typed/event-bus.md) { #dependency }

@@@ note
## Introduction

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.
@@include[typed/event-bus.md](typed/event-bus.md) { #introduction-start }

@@@

This mechanism is used in different places within Akka, e.g. the @ref:[Event Stream](#event-stream).
Implementations can make use of the specific building blocks presented below.
Scala
: @@snip [EventBus.scala](/akka-actor/src/main/scala/akka/event/EventBus.scala) { #event-bus-api }

An event bus must define the following three @scala[abstract types]@java[type parameters]:
Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #event-bus-api }

* `Event` is the type of all events published on that bus
* `Subscriber` is the type of subscribers allowed to register on that event bus
* `Classifier` defines the classifier to be used in selecting
subscribers for dispatching events
@@include[typed/event-bus.md](typed/event-bus.md) { #introduction-end }

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
implementation of the existing ones on @extref[github](github:akka-actor/src/main/scala/akka/event/EventBus.scala)
@@include[typed/event-bus.md](typed/event-bus.md) { #classifiers-intro }

### 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.
This can be compared to tuning in on a radio station. The @scala[trait
@scaladoc[LookupClassification](akka.event.LookupClassification)]@java[abstract class @scaladoc[LookupEventBus](akka.event.japi.LookupEventBus)] is still generic in that it abstracts over how to
compare subscribers and how exactly to classify them.

The necessary methods to be implemented are illustrated with the following example:
@@include[typed/event-bus.md](typed/event-bus.md) { #lookup-classification-start }

Scala
: @@snip [EventBusDocSpec.scala](/akka-docs/src/test/scala/docs/event/EventBusDocSpec.scala) { #lookup-bus }
Expand All @@ -61,19 +42,11 @@ Scala
Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #lookup-bus-test }

This classifier is efficient in case no subscribers exist for a particular event.
@@include[typed/event-bus.md](typed/event-bus.md) { #lookup-classification-end }

### 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
classifier hierarchy.

The necessary methods to be implemented are illustrated with the following example:
@@include[typed/event-bus.md](typed/event-bus.md) { #subchannel-classification-start }

Scala
: @@snip [EventBusDocSpec.scala](/akka-docs/src/test/scala/docs/event/EventBusDocSpec.scala) { #subchannel-bus }
Expand All @@ -89,21 +62,11 @@ Scala
Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #subchannel-bus-test }

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).
@@include[typed/event-bus.md](typed/event-bus.md) { #subchannel-classification-end }

### 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).

The necessary methods to be implemented are illustrated with the following example:
@@include[typed/event-bus.md](typed/event-bus.md) { #scanning-classification-start }

Scala
: @@snip [EventBusDocSpec.scala](/akka-docs/src/test/scala/docs/event/EventBusDocSpec.scala) { #scanning-bus }
Expand All @@ -119,21 +82,16 @@ Scala
Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #scanning-bus-test }

This classifier takes always a time which is proportional to the number of
subscriptions, independent of how many actually match.
@@include[typed/event-bus.md](typed/event-bus.md) { #scanning-classification-end }


### Actor Classification

This classification was originally developed specifically for implementing
@ref:[DeathWatch](actors.md#deathwatch): subscribers as well as classifiers are of
@ref:[DeathWatch](actors.md#lifecycle-monitoring-aka-deathwatch): subscribers as well as classifiers are of
type @apidoc[actor.ActorRef].

This classification requires an @apidoc[actor.ActorSystem] in order to perform book-keeping
operations related to the subscribers being Actors, which can terminate without first
unsubscribing from the EventBus. ManagedActorClassification maintains a system Actor which
takes care of unsubscribing terminated actors automatically.

The necessary methods to be implemented are illustrated with the following example:
@@include[typed/event-bus.md](typed/event-bus.md) { #actor-classification-start }

Scala
: @@snip [EventBusDocSpec.scala](/akka-docs/src/test/scala/docs/event/EventBusDocSpec.scala) { #actor-bus }
Expand All @@ -149,8 +107,8 @@ Scala
Java
: @@snip [EventBusDocTest.java](/akka-docs/src/test/java/jdocs/event/EventBusDocTest.java) { #actor-bus-test }

This classifier is still is generic in the event type, and it is efficient for
all use cases.
@@include[typed/event-bus.md](typed/event-bus.md) { #actor-classification-end }


## Event Stream

Expand Down
1 change: 1 addition & 0 deletions akka-docs/src/main/paradox/index-utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

@@@ index

* [event-bus](typed/event-bus.md)
* [logging](typed/logging.md)
* [common/circuitbreaker](common/circuitbreaker.md)
* [futures](futures.md)
Expand Down
Loading

0 comments on commit e52582f

Please sign in to comment.