com.netflix.eventbus.spi
Interface EventBus

All Known Implementing Classes:
EventBusImpl

public interface EventBus

An event bus for in-process publish-subscribe communication between components. It aids in de-coupling publishers and subscribers and provides a simple way of publishing, filtering and listening to events.

The various facets of the event bus is defined as follows:

Publishers

Publisher of events can publish the events in two modes as follows:

Events

An event can be any arbitrary object and does not require any semantics.

Subscribers

Subscribers are the components that are interested in events generated by the publishers. A subscriber requests interest in certain events by providing a method with the annotation Subscribe and having just one argument, the event object itself.
Event - Subscriber mapping
Any subscriber method taking an event object of Class X as argument is expected to be interested in all events published corresponding to its superclasses and implemented interface (directly or via a superclass). In short if the invocation of Class.isAssignableFrom(Class) on the event object's class with the subscriber class as argument returns true, then that subscriber is interested in the event.
Dispatch mode
All subscribers are async and isolated with any other listener i.e. a slow listener does not impact other listeners for the same event. At the same time, the event data is not copied for this isolation. The overhead of this isolation will just be the cost of storing references to these events in each listeners queue.

A subscriber can indicate if it favors synchronous event consumption: This is just a backdoor and should be used with caution as then the consumption and filtering will happen in the publishing thread. Also, this behavior can be overridden if the property SyncSubscribersGatekeeper.ALLOW_SYNC_SUBSCRIBERS is set to false. In that case, the events will be sent to the subscriber asynchronously. See SyncSubscribersGatekeeper for more details.

There are multiple facets of this async dispatch mode which are described below:

Event filtering

Events can be filtered both before publishing and before receiving the same in the subscriber. Filtering at the subscriber end is done per subscriber. Filtering at the publisher side rejects the event.
All filters for the event must return true for the event to be published/received Event filters can be expressed as a filter language as available under com.netflix.eventbus.filter.lang. Such a filter can then be converted into an EventFilter using EventFilterCompiler For relatively easy way of programmatic creation of filters, one can use the utility/factory class com.netflix.eventbus.filter.EventFilters.
Subscriber level filtering is done in the consumer thread and not in the thread of the event publisher. This alleviates the overhead of event publishing that may be introduced by slow filter evaluation. However, it does have a side effect on the speed of event processing by the consumer and hence may increase the backlog for particular consumers. In any case, the impact of slow filters is isolated to the consumers and does not plague the event publishing that typically will happen in the client's request processing thread.

Runtime event - subscriber binding

Eventbus subscribers, by design, are statically tied to a particular type of object i.e. the class of the event it is interested in. This in most cases is beneficial and easy to use, however, in some cases (typically event agnostic, middlemen, which stores the event for later investigation), the event processing is much the same irrespective of the type of event it receives. In such a case, it will be an overhead (even if possible) to define a subscriber for each kind of event existing in the system. DynamicSubscriber is a way to achieve runtime binding of an event to a subscriber.


Field Summary
static int CONSUMER_QUEUE_FULL_RETRY_MAX_DEFAULT
           
static java.lang.String CONSUMER_QUEUE_FULL_RETRY_MAX_PROP_NAME
           
static int CONSUMER_QUEUE_SIZE_DEFAULT
           
static java.lang.String CONSUMER_QUEUE_SIZE_DEFAULT_PROP_NAME
           
 
Method Summary
 void addFilterForEvent(EventFilter filter, java.lang.Class<?> eventClass)
          Adds a publisher level filter for the passed event type.
 void addFilterForSubscriber(EventFilter filter, SubscriberInfo subscriberInfo)
          Adds the passed filter for the passed subscriber method.
 void clearFiltersForEvent(java.lang.Class<?> eventClass)
          Removes all the filters for the passed event type.
 void clearFiltersForSubscriber(SubscriberInfo subscriberInfo)
          Removes all filters for the passed subscriber method.
 void disableCatchAllSubscriber()
          Disables the CatchAllSubscriber for this eventbus.
 boolean enableCatchAllSubscriber(java.util.concurrent.BlockingQueue<?> catchAllSink)
          Enables the CatchAllSubscriber for this eventbus with the sink for the subscriber as the passed BlockingQueue instance.
 java.util.Set<java.lang.Class<?>> getAllRegisteredEventTypes()
          Returns all the event types which have atleast a subscriber or a filter defined in this event bus.
 java.util.Set<SubscriberInfo> getAllSubscribers()
          Returns a set of subscribers that are registered with this event bus.
 java.util.Set<SubscriberInfo> getAllSubscribersForAnEvent(java.lang.Class<?> eventType)
          Returns a set of subscribers for that passed event type that are registered with this event bus.
 java.util.Set<EventFilter> getFilterForASubscriber(SubscriberInfo subscriberInfo)
          The set of event filters attached to the passed subscriber.
 java.util.Set<EventFilter> getFiltersForAnEvent(java.lang.Class<?> eventType)
          The set of event filters attached to the passed event type.
 void publish(java.lang.Object event)
          Publishes the passed event object.
 void publishIffNotDead(EventCreator creator, java.lang.Class<?>... eventTypes)
          Publishes events iff there is atleast one listener for any of the passed event types.
 void registerSubscriber(EventFilter filter, java.lang.Object subscriber)
          Registers a subscriber which will be invoked iff the filter passes for the event to be published.
 void registerSubscriber(java.lang.Object subscriber)
          Registers a subscriber without any filters.
 void removeFiltersForEvent(java.lang.Class<?> eventClass, EventFilter... filters)
          Removes the passed filters for the passed event type.
 void removeFiltersForSubscriber(SubscriberInfo subscriberInfo, EventFilter... filters)
          Removes the passed filters for the passed subscriber.
 java.util.Set<java.lang.Object> unregisterSubscriber(java.lang.Class<?> subscriberClass)
          Removes the subscriber class (all of its subscriber methods) from the event bus.
 boolean unregisterSubscriber(java.lang.Object subscriber)
          Removes the subscriber instance (all of its subscriber methods) from the event bus.
 

Field Detail

CONSUMER_QUEUE_FULL_RETRY_MAX_PROP_NAME

static final java.lang.String CONSUMER_QUEUE_FULL_RETRY_MAX_PROP_NAME
See Also:
Constant Field Values

CONSUMER_QUEUE_FULL_RETRY_MAX_DEFAULT

static final int CONSUMER_QUEUE_FULL_RETRY_MAX_DEFAULT
See Also:
Constant Field Values

CONSUMER_QUEUE_SIZE_DEFAULT_PROP_NAME

static final java.lang.String CONSUMER_QUEUE_SIZE_DEFAULT_PROP_NAME
See Also:
Constant Field Values

CONSUMER_QUEUE_SIZE_DEFAULT

static final int CONSUMER_QUEUE_SIZE_DEFAULT
See Also:
Constant Field Values
Method Detail

publish

void publish(java.lang.Object event)
Publishes the passed event object. The following is done on receiving this call:
  • Apply all publisher level filters for this event. If any of the filter returns false then exit.
  • Find all interested subscribers.
  • Apply filters per interested subscriber.
  • For the subscribers that pass the filtering criterion, enqueue the event to the subscriber's queue (async dispatch)

Parameters:
event - Event to publish.

publishIffNotDead

void publishIffNotDead(EventCreator creator,
                       java.lang.Class<?>... eventTypes)
Publishes events iff there is atleast one listener for any of the passed event types. See EventBus javadocs for details about conditional event publishing.
The following is done on receiving this call:
  • Find all interested subscribers.
  • Invoke EventCreator.createEvent(java.util.Set) with only the event types that have atleast one listener.
  • Apply all publisher level filters for this event. If any of the filter returns false then exit.
  • Find all subscribers corresponding to the events created by the above call.
  • For all subscribers, invoke the filters.
  • For the subscribers that pass the filtering criterion, enqueue the event(s) to the subscriber's queue (async dispatch)
This style of publishing must only be used if creating an event object is costly (either due to the size of the object or work required to create such an object) otherwise, the complexity is not worth the effort.

Parameters:
creator - Event creator to be invoked iff there is atleast one listener for the event types.
eventTypes - Event types for which the events are to be published.

registerSubscriber

void registerSubscriber(@Nullable
                        EventFilter filter,
                        java.lang.Object subscriber)
                        throws InvalidSubscriberException
Registers a subscriber which will be invoked iff the filter passes for the event to be published. This method will attach the filter to all subscriber methods in the passed subscriber. If you need to attach different filters to different methods, then you should register the subscriber without the filter registerSubscriber(Object) and then register each filter using addFilterForSubscriber(com.netflix.eventbus.spi.EventFilter, com.netflix.eventbus.spi.SubscriberInfo)
See EventBus javadocs for details about subscribers, filters, event-subscriber association and dispatch mode.

Parameters:
filter - Filter.
subscriber - Subscriber to register.
Throws:
InvalidSubscriberException - If the passed subscriber is invalid.

registerSubscriber

void registerSubscriber(java.lang.Object subscriber)
                        throws InvalidSubscriberException
Registers a subscriber without any filters. See EventBus javadocs for details about subscribers, filters, event-subscriber association and dispatch mode.

Parameters:
subscriber - Subscriber to register.
Throws:
InvalidSubscriberException - If the passed subscriber is invalid.

enableCatchAllSubscriber

boolean enableCatchAllSubscriber(java.util.concurrent.BlockingQueue<?> catchAllSink)
Enables the CatchAllSubscriber for this eventbus with the sink for the subscriber as the passed BlockingQueue instance.

Parameters:
catchAllSink - The sink for the CatchAllSubscriber
Returns:
true if the passes sink was successfully attached, iff there is no sink already present.

disableCatchAllSubscriber

void disableCatchAllSubscriber()
Disables the CatchAllSubscriber for this eventbus.


unregisterSubscriber

java.util.Set<java.lang.Object> unregisterSubscriber(java.lang.Class<?> subscriberClass)
Removes the subscriber class (all of its subscriber methods) from the event bus.
If there are more than one instance of the passed class registered with this event bus, all of them are removed. All unconsumed events are rejected.

Parameters:
subscriberClass - Subscriber class to unregister.
Returns:
Set of subscriber instances that were removed by this unregister. More than one subscriber instances can be registered with this bus for the same subscriber class. In such a case, there will be more than one instances in the list.

unregisterSubscriber

boolean unregisterSubscriber(java.lang.Object subscriber)
Removes the subscriber instance (all of its subscriber methods) from the event bus.
If there are other subscriber instances associated with the class of the passed subscriber, they are left untouched. This should be the preferred mode of unregistration when more than one instances of the same subscriber class are registered and only one is to be removed. All unconsumed events are rejected.

Parameters:
subscriber - Subscriber instance to unregister.
Returns:
true if the subscriber instance was unregistered, false otherwise.

addFilterForSubscriber

void addFilterForSubscriber(EventFilter filter,
                            SubscriberInfo subscriberInfo)
Adds the passed filter for the passed subscriber method. See EventBus javadocs for details about subscribers & filters.

Parameters:
filter - Filter to attach.
subscriberInfo - Subscriber info. This can be retrieved by methods getAllSubscribersForAnEvent(Class) or getAllSubscribers()

removeFiltersForSubscriber

void removeFiltersForSubscriber(SubscriberInfo subscriberInfo,
                                EventFilter... filters)
Removes the passed filters for the passed subscriber. See EventBus javadocs for details about subscribers & filters.

Parameters:
subscriberInfo - Subscriber info. This can be retrieved by methods getAllSubscribersForAnEvent(Class) or getAllSubscribers()
filters - Filters to remove.

clearFiltersForSubscriber

void clearFiltersForSubscriber(SubscriberInfo subscriberInfo)
Removes all filters for the passed subscriber method. See EventBus javadocs for details about subscribers & filters.

Parameters:
subscriberInfo - Subscriber info. This can be retrieved by methods getAllSubscribersForAnEvent(Class) or getAllSubscribers()

addFilterForEvent

void addFilterForEvent(EventFilter filter,
                       java.lang.Class<?> eventClass)
Adds a publisher level filter for the passed event type. See EventBus javadocs for details about publishers & filters.

Parameters:
filter - Filter
eventClass - The class of the event for which the filter is to be attached.

removeFiltersForEvent

void removeFiltersForEvent(java.lang.Class<?> eventClass,
                           EventFilter... filters)
Removes the passed filters for the passed event type. See EventBus javadocs for details about publishers & filters.

Parameters:
eventClass - The class of the event for which the filter are to be removed.
filters - Filters to be removed

clearFiltersForEvent

void clearFiltersForEvent(java.lang.Class<?> eventClass)
Removes all the filters for the passed event type. See EventBus javadocs for details about publishers & filters.

Parameters:
eventClass - The class of the event for which the filter are to be cleared.

getAllSubscribers

java.util.Set<SubscriberInfo> getAllSubscribers()
Returns a set of subscribers that are registered with this event bus.
The details of the filter attached (if any) can be retrieved by the method getFilterForASubscriber(com.netflix.eventbus.spi.SubscriberInfo)

Returns:
An immutable set of currently registered subscribers for the passed event type.

getAllSubscribersForAnEvent

java.util.Set<SubscriberInfo> getAllSubscribersForAnEvent(java.lang.Class<?> eventType)
Returns a set of subscribers for that passed event type that are registered with this event bus.
The details of the filter attached (if any) can be retrieved by the method getFilterForASubscriber(SubscriberInfo)

Parameters:
eventType - Event for which the subscribers are to be retrieved.
Returns:
An immutable set of currently registered subscribers.

getFilterForASubscriber

java.util.Set<EventFilter> getFilterForASubscriber(SubscriberInfo subscriberInfo)
The set of event filters attached to the passed subscriber.

Parameters:
subscriberInfo - Subscriber info. This can be retrieved by methods getAllSubscribersForAnEvent(Class) or getAllSubscribers()
Returns:
Immutable set of attached filters. Empty list if none exists.

getFiltersForAnEvent

java.util.Set<EventFilter> getFiltersForAnEvent(java.lang.Class<?> eventType)
The set of event filters attached to the passed event type.

Parameters:
eventType - Event type for which the filters are to be retrieved.
Returns:
Immutable set of attached filters. Empty list if none exists.

getAllRegisteredEventTypes

java.util.Set<java.lang.Class<?>> getAllRegisteredEventTypes()
Returns all the event types which have atleast a subscriber or a filter defined in this event bus.

Returns:
Unmodifiable set of all event types registered with this event bus.