Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.netflix.eventbus.spi;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
/**
* 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:
*
Unconditional: The event gets published irrespective of the fact whether there are any listeners or not.
If there are no listeners, the event will be discarded.
Conditional: The event will be published iff there is atleast one listener for that event at the time
publish is called. This style should be used only when creating the event object itself is costly, otherwise,
the complexity is not worth the effort. In this case, the event creation is delayed using {@link EventCreator}.
In case, a listener that showed interest in the event unregisters before receiving the same, it will not receive this
event. On the other hand, if any new listener gets registered for this event after the initial check is made, it will
receive this event, provided it gets registered before the event starts to get published.
The interest of the listener for this event will only be based on the event type and not the event data as the data is
not available initially. This essentially means that such an event may be filtered-out by the listener based on the
event data when it actually receives the event.
*
*
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
* {@link 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 {@link 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 {@link SyncSubscribersGatekeeper#ALLOW_SYNC_SUBSCRIBERS} is set to false. In that case, the
* events will be sent to the subscriber asynchronously. See {@link SyncSubscribersGatekeeper} for more details.
*
* There are multiple facets of this async dispatch mode which are described below:
*
Slow subscribers: In case the subscriber queue is full, the older events are rejected, one at a time and
the event bus retries to offer the event to the subscriber, after each removal. This retry is capped at a default value
{@link EventBus#CONSUMER_QUEUE_FULL_RETRY_MAX_DEFAULT} which can be overridden by a dynamic property:
{@link EventBus#CONSUMER_QUEUE_FULL_RETRY_MAX_PROP_NAME}. If all the retries fail, the event is rejected.
Event batch: If the subscribers wish to process the events in batches, then they can annotate themselves with
an appropriate {@link com.netflix.eventbus.spi.Subscribe.BatchingStrategy}. Care must be taken while batching as the
rejections also happens in batch when the subscribers are slow.
Queue size: A subscriber can optionally define a queue size for the async dispatch using
{@link com.netflix.eventbus.spi.Subscribe#queueSize()}. The default value for this queue size is
{@link EventBus#CONSUMER_QUEUE_SIZE_DEFAULT} which can be changed via the fast property:
{@link EventBus#CONSUMER_QUEUE_SIZE_DEFAULT_PROP_NAME}
*
*
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 {@link com.netflix.eventbus.filter.lang}.
* Such a filter can then be converted into an {@link EventFilter} using {@link com.netflix.eventbus.filter.EventFilterCompiler}
* For relatively easy way of programmatic creation of filters, one can use the utility/factory class
* {@link 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. {@link DynamicSubscriber} is a way to achieve runtime binding of an event
* to a subscriber.
*
* @author Nitesh Kant ([email protected])
*/
public interface EventBus {
public static final String CONSUMER_QUEUE_FULL_RETRY_MAX_PROP_NAME = "eventbus.consumer.queuefull.maxretries";
public static final int CONSUMER_QUEUE_FULL_RETRY_MAX_DEFAULT = 5;
public static final String CONSUMER_QUEUE_SIZE_DEFAULT_PROP_NAME = "eventbus.consumer.queue.size.default";
public static final int CONSUMER_QUEUE_SIZE_DEFAULT = 1000;
/**
* 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)
*
* @param event Event to publish.
*/
void publish(Object event);
/**
* Publishes events iff there is atleast one listener for any of the passed event types. See {@link EventBus}
* javadocs for details about conditional event publishing.
*
* The following is done on receiving this call:
*
Find all interested subscribers.
Invoke {@link 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.
*
* @param creator Event creator to be invoked iff there is atleast one listener for the event types.
* @param eventTypes Event types for which the events are to be published.
*/
void publishIffNotDead(EventCreator creator, Class>... eventTypes);
/**
* 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
* {@link EventBus#registerSubscriber(Object)} and then register each filter using
* {@link EventBus#addFilterForSubscriber}
* See {@link EventBus} javadocs for details about subscribers, filters, event-subscriber association and dispatch
* mode.
*
* @param filter Filter.
* @param subscriber Subscriber to register.
*
* @throws InvalidSubscriberException If the passed subscriber is invalid.
*/
void registerSubscriber(@Nullable EventFilter filter, Object subscriber) throws InvalidSubscriberException;
/**
* Registers a subscriber without any filters.
* See {@link EventBus} javadocs for details about subscribers, filters, event-subscriber association and dispatch
* mode.
*
* @param subscriber Subscriber to register.
*
* @throws InvalidSubscriberException If the passed subscriber is invalid.
*/
void registerSubscriber(Object subscriber) throws InvalidSubscriberException;
/**
* Enables the {@link CatchAllSubscriber} for this eventbus with the sink for the subscriber as the passed
* {@link BlockingQueue} instance.
*
* @param catchAllSink The sink for the {@link CatchAllSubscriber}
*
* @return true if the passes sink was successfully attached, iff there is no sink already present.
*/
boolean enableCatchAllSubscriber(BlockingQueue> catchAllSink);
/**
* Disables the {@link CatchAllSubscriber} for this eventbus.
*/
void disableCatchAllSubscriber();
/**
* 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.
*
* @param subscriberClass Subscriber class to unregister.
*
* @return 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.
*/
Set