Interface EventDispatcher
-
- All Known Implementing Classes:
DefaultEventDispatcher,ReplayingEventDispatcher,SinksEventDispatcher
public interface EventDispatcherDistributes events to subscribers.Eventinstances can be published over this class and dispatched to all subscribers.Individual events can be published to subscribers using
publish(Event)while they can be used to consumed throughon(Class)giving the properEventclass as argument.Each event can be consumed using the following pattern:
dispatcher.on(MessageCreatedEvent.class) .subscribe(event -> event.getMessage());While events can be published through:fluxOfEvents.doOnNext(dispatcher::publish) .subscribe();
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interfaceEventDispatcher.Builder
-
Field Summary
Fields Modifier and Type Field Description static Supplier<Scheduler>DEFAULT_EVENT_SCHEDULERstatic Loggerlog
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Deprecated Methods Modifier and Type Method Description static EventDispatcherbuffering()Create anEventDispatcherthat will buffer incoming events to retain all startup events as each shard connects at the cost of increased memory usage and potentialOutOfMemoryErrorif events are not consumed.static EventDispatcher.Builderbuilder()Create anEventDispatcherbuilder.default Flux<Event>on(ReactiveEventAdapter adapter)Applies a givenadapterto all events from this dispatcher.<E extends Event>
Flux<E>on(Class<E> eventClass)default <E extends Event,T>
Flux<T>on(Class<E> eventClass, Function<E,Publisher<T>> mapper)voidpublish(Event event)Publishes anEventto the dispatcher.static EventDispatcherreplaying()Create anEventDispatcherthat is capable of replaying up to 2 minutes worth of important events likeGuildCreateEventandGatewayLifecycleEventthat arrive while no subscribers are connected to all late subscribers, as long as they subscribe within the replay window of 5 seconds.static EventDispatcherreplayingWithSize(int historySize)Create anEventDispatcherthat will replay up tohistorySizeelements to late subscribers.static EventDispatcherreplayingWithTimeout(Duration maxAge)Create anEventDispatcherthat is time-bounded and retains all elements whose age is at mostmaxAge, replaying them to late subscribers.voidshutdown()Signal that this event dispatcher must terminate and release its resources.static EventDispatcherwithEarliestEvents(int bufferSize)Create anEventDispatcherthat will buffer incoming events up to the givenbufferSizeelements, where subsequent events will be dropped in favor of retaining the earliest ones.static EventDispatcherwithLatestEvents(int bufferSize)Deprecated.due to Processor API being deprecated, we recommend moving toreplayingWithSize(int)for a dispatcher that is able to retain a given number of latest events
-
-
-
Method Detail
-
on
<E extends Event> Flux<E> on(Class<E> eventClass)
Retrieves aFluxwith elements of the givenEventtype. ThisFluxhas to be subscribed to in order to start processing. SeeEventclass for the list of possible event classes.Note: Errors occurring while processing events will terminate your sequence. If you wish to use a version capable of handling errors for you, use
on(Class, Function). See Reactive Streams Spec explaining this behavior.A recommended pattern to use this method is wrapping your code that may throw exceptions within a
flatMapblock and useMono.onErrorResume(Function),Flux.onErrorResume(Function)or equivalent methods to maintain the sequence active:client.getEventDispatcher().on(MessageCreateEvent.class) .flatMap(event -> myCodeThatMightThrow(event) .onErrorResume(error -> { // log and then discard the error to keep the sequence alive log.error("Failed to handle event!", error); return Mono.empty(); })) .subscribe();For more alternatives to handling errors, please see Error Handling docs page.
- Type Parameters:
E- the type of the event class- Parameters:
eventClass- the event class to obtain events from- Returns:
- a new
Fluxwith the requested events
-
on
default <E extends Event,T> Flux<T> on(Class<E> eventClass, Function<E,Publisher<T>> mapper)
Retrieves aFluxwith elements of the givenEventtype, to be processed through a givenFunctionupon subscription. Errors occurring within the mapper will be logged and discarded, preventing the termination of the "infinite" event sequence. SeeEventclass for the list of possible event classes.There are multiple ways of using this event handling method, for example:
client.on(MessageCreateEvent.class, event -> { // myCodeThatMightThrow should return a Reactor type (Mono or Flux) return myCodeThatMightThrow(event); }) .subscribe(); client.on(MessageCreateEvent.class, event -> { // myCodeThatMightThrow *can* be blocking, so wrap it in a Reactor type return Mono.fromRunnable(() -> myCodeThatMightThrow(event)); }) .subscribe();Continuing the chain after
on(class, event -> ...)will require your own error handling strategy. Check the docs foron(Class)for more details.- Type Parameters:
E- the type of the event classT- the type of the event mapper function- Parameters:
eventClass- the event class to obtain events frommapper- an event mapping function called on each event. If you do not wish to perform further operations you can returnMono.empty().- Returns:
- a new
Fluxwith the type resulting from the given event mapper
-
on
default Flux<Event> on(ReactiveEventAdapter adapter)
Applies a givenadapterto all events from this dispatcher. Errors occurring within the mapper will be logged and discarded, preventing the termination of the "infinite" event sequence. This variant allows you to have a single subscriber to this dispatcher, which is useful to collect all startup events.A standard approach to this method is to subclass
ReactiveEventAdapter, overriding the methods you want to listen for:client.on(new ReactiveEventAdapter() { public Publisher<?> onReady(ReadyEvent event) { return Mono.fromRunnable(() -> System.out.println("Connected as " + event.getSelf().getTag())); } public Publisher<?> onMessageCreate(MessageCreateEvent event) { if (event.getMessage().getContent().equals("!ping")) { return event.getMessage().getChannel() .flatMap(channel -> channel.createMessage("Pong!")); } return Mono.empty(); } }).subscribe(); // nothing happens until you subscribeEach method requires a
Publisherreturn likeMonoorFluxand all errors will be logged and discarded. To use a synchronous implementation you can wrap your code withMono.fromRunnable(Runnable).Continuing the chain will require your own error handling strategy. Check the docs for
on(Class)for more details.- Parameters:
adapter- an adapter meant to be subclassed with its appropriate methods overridden- Returns:
- a new
Fluxwith the type resulting from the given event mapper
-
publish
void publish(Event event)
Publishes anEventto the dispatcher. Might throw an unchecked exception if the dispatcher can't handle this event.- Parameters:
event- theEventto publish
-
shutdown
void shutdown()
Signal that this event dispatcher must terminate and release its resources.
-
builder
static EventDispatcher.Builder builder()
Create anEventDispatcherbuilder. It can be configured with a customFluxProcessorfor events, a customFluxSink.OverflowStrategyto handle backpressure and a customSchedulerto dispatch events.- Returns:
- a
EventDispatcher.Builder
-
buffering
static EventDispatcher buffering()
Create anEventDispatcherthat will buffer incoming events to retain all startup events as each shard connects at the cost of increased memory usage and potentialOutOfMemoryErrorif events are not consumed. Startup events collected before the first subscription are only forwarded to that subscriber.- Returns:
- a buffering
EventDispatcherbacked by anEmitterProcessor
-
withEarliestEvents
static EventDispatcher withEarliestEvents(int bufferSize)
Create anEventDispatcherthat will buffer incoming events up to the givenbufferSizeelements, where subsequent events will be dropped in favor of retaining the earliest ones. Startup events collected before the first subscription are only forwarded to that subscriber.- Parameters:
bufferSize- the number of events to keep in the backlog- Returns:
- an
EventDispatcherkeeping the earliest events up tobufferSize
-
withLatestEvents
static EventDispatcher withLatestEvents(int bufferSize)
Deprecated.due to Processor API being deprecated, we recommend moving toreplayingWithSize(int)for a dispatcher that is able to retain a given number of latest eventsCreate anEventDispatcherthat will buffer incoming events up to the givenbufferSizeelements, where earliest events will be dropped in favor of retaining the latest ones. Startup events collected before the first subscription are only forwarded to that subscriber.- Parameters:
bufferSize- the number of events to keep in the backlog- Returns:
- an
EventDispatcherkeeping the latest events backed by anEmitterProcessor
-
replaying
static EventDispatcher replaying()
Create anEventDispatcherthat is capable of replaying up to 2 minutes worth of important events likeGuildCreateEventandGatewayLifecycleEventthat arrive while no subscribers are connected to all late subscribers, as long as they subscribe within the replay window of 5 seconds. After the replay window has closed, it behaves like an emitter event dispatcher.This allows controlling the memory overhead of dispatchers like
buffering()while still keeping a record of important events to all late subscribers, even after login has completed.This dispatcher can be customized through the use of
ReplayingEventDispatcher.builder().- Returns:
- an
EventDispatcherthat is capable of replaying events to late subscribers
-
replayingWithTimeout
static EventDispatcher replayingWithTimeout(Duration maxAge)
Create anEventDispatcherthat is time-bounded and retains all elements whose age is at mostmaxAge, replaying them to late subscribers. Be aware that using this type of dispatcher with operators such asFlux.retry()orFlux.repeat()that re-subscribe to the dispatcher will observe the same elements as the backlog contains.- Parameters:
maxAge- the maximum age of the contained items- Returns:
- an
EventDispatcherthat will replay elements up tomaxAgeduration to late subscribers
-
replayingWithSize
static EventDispatcher replayingWithSize(int historySize)
Create anEventDispatcherthat will replay up tohistorySizeelements to late subscribers. Be aware that using this type of dispatcher with operators such asFlux.retry()orFlux.repeat()that re-subscribe to the dispatcher will observe the same elements as the backlog contains.- Parameters:
historySize- the backlog size or maximum items retained for replay- Returns:
- an
EventDispatcherthat will replay up tohistorySizeelements to late subscribers
-
-