Back to Akka

Classic Event Bus

akka-docs/src/main/paradox/event-bus.md

10.1.08.4 KB
Original Source

Classic Event Bus

@@includeincludes.md { #actor-api } For the full documentation of this feature and for new projects see @ref:Event Bus.

Dependency

@@includetyped/event-bus.md { #dependency }

Introduction

@@includetyped/event-bus.md { #introduction-start }

Scala : @@snip EventBus.scala { #event-bus-api }

Java : @@snip EventBusDocTest.java { #event-bus-api }

@@includetyped/event-bus.md { #introduction-end }

Classifiers

@@includetyped/event-bus.md { #classifiers-intro }

Lookup Classification

@@includetyped/event-bus.md { #lookup-classification-start }

Scala : @@snip EventBusDocSpec.scala { #lookup-bus }

Java : @@snip EventBusDocTest.java { #lookup-bus }

A test for this implementation may look like this:

Scala : @@snip EventBusDocSpec.scala { #lookup-bus-test }

Java : @@snip EventBusDocTest.java { #lookup-bus-test }

@@includetyped/event-bus.md { #lookup-classification-end }

Subchannel Classification

@@includetyped/event-bus.md { #subchannel-classification-start }

Scala : @@snip EventBusDocSpec.scala { #subchannel-bus }

Java : @@snip EventBusDocTest.java { #subchannel-bus }

A test for this implementation may look like this:

Scala : @@snip EventBusDocSpec.scala { #subchannel-bus-test }

Java : @@snip EventBusDocTest.java { #subchannel-bus-test }

@@includetyped/event-bus.md { #subchannel-classification-end }

Scanning Classification

@@includetyped/event-bus.md { #scanning-classification-start }

Scala : @@snip EventBusDocSpec.scala { #scanning-bus }

Java : @@snip EventBusDocTest.java { #scanning-bus }

A test for this implementation may look like this:

Scala : @@snip EventBusDocSpec.scala { #scanning-bus-test }

Java : @@snip EventBusDocTest.java { #scanning-bus-test }

@@includetyped/event-bus.md { #scanning-classification-end }

Actor Classification

This classification was originally developed specifically for implementing @ref:DeathWatch: subscribers as well as classifiers are of type @apidoc[actor.ActorRef].

@@includetyped/event-bus.md { #actor-classification-start }

Scala : @@snip EventBusDocSpec.scala { #actor-bus }

Java : @@snip EventBusDocTest.java { #actor-bus }

A test for this implementation may look like this:

Scala : @@snip EventBusDocSpec.scala { #actor-bus-test }

Java : @@snip EventBusDocTest.java { #actor-bus-test }

@@includetyped/event-bus.md { #actor-classification-end }

Event Stream

The event stream is the main event bus of each actor system: it is used for carrying @ref:log messages and @ref:Dead Letters and may be used by the user code for other purposes as well. It uses @ref:Subchannel Classification which enables registering to related sets of channels. The following example demonstrates how a simple subscription works. Given a simple actor:

@@@ div { .group-scala }

@@snip LoggingDocSpec.scala { #deadletters }

@@@

@@@ div { .group-java }

@@snip LoggingDocTest.java { #imports-deadletter }

@@snip LoggingDocTest.java { #deadletter-actor }

it can be subscribed like this:

@@snip LoggingDocTest.java { #deadletters }

@@@

It is also worth pointing out that thanks to the way the subchannel classification is implemented in the event stream, it is possible to subscribe to a group of events, by subscribing to their common superclass as demonstrated in the following example:

Scala : @@snip LoggingDocSpec.scala { #superclass-subscription-eventstream }

Java : @@snip LoggingDocTest.java { #superclass-subscription-eventstream }

Similarly to @ref:Actor Classification, @apidoc[event.EventStream] will automatically remove subscribers 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 Publish Subscribe in Cluster.

@@@

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:

text
akka {
  loggers = ["akka.event.Logging$DefaultLogger"]
}

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:

Scala : @@@vars system.eventStream.setLogLevel(Logging.DebugLevel) @@@

Java : @@@vars system.eventStream.setLogLevel(Logging.DebugLevel()); @@@

This means that log events for a level which will not be logged are typically not dispatched at all (unless manual subscriptions to the respective event class have been done)

Dead Letters

As described at @ref:Stopping actors, 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 @apidoc[DeadLetter]. This wrapper holds the original sender, receiver and message of the envelope which was redirected.

Some internal messages (marked with the @apidoc[DeadLetterSuppression] @scala[trait]@java[interface]) will not end up as dead letters like normal messages. These are by design safe and expected to sometimes arrive at a terminated actor and since they are nothing to worry about, they are suppressed from the default dead letters logging mechanism.

However, in case you find yourself in need of debugging these kinds of low level suppressed dead letters, it's still possible to subscribe to them explicitly:

Scala : @@snip LoggingDocSpec.scala { #suppressed-deadletters }

Java : @@snip LoggingDocTest.java { #suppressed-deadletters }

or all dead letters (including the suppressed ones):

Scala : @@snip LoggingDocSpec.scala { #all-deadletters }

Java : @@snip LoggingDocTest.java { #all-deadletters }

Other Uses

The event stream is always there and ready to be used, you can publish your own events (it accepts @scala[@scaladocAnyRef]@java[@javadocObject]) and subscribe listeners to the corresponding JVM classes.