Hannes
Hannes

Reputation: 5282

Guava EventBus: Dispatching event to multiple subscribers

Since the Guava's EventBus documentation is rather short I ask it here:

Is there a way to dispatch events to multiple subscribers or are events always consumed by the first suitable subscriber?

If the latter is the case, would it better to extend the EventBus class in order to add such a feature or to implement the whole event bus logic in the own application?

Upvotes: 1

Views: 1884

Answers (2)

maaartinus
maaartinus

Reputation: 46492

If the latter is the case, would it better to extend the EventBus class in order to add such a feature or to implement the whole event bus logic in the own application?

I guess, all you need is to add a handled attribute to the event and add a testAndSet to all your handlers. Doing it manually is surely error-prone, if you have many of them.

You could create a wrapper for your event, which wouldn't let you access it without calling it. Something like

@RequiredArgsConstructor
class WrappedEvent<E extends MyEvent> {
    private final E event;
    private boolean handled;

    Optional<E> getAndMarkHandledUnlessHandled() {
        if (handled) {
            return Optional.empty();
        } else {
            handled = true;
            return Optional.of(event);
        }
    }
}

or do it in more functional way like callAndMarkHandledUnlessHandled(Consumer<E> consumer). For asynchronous dispatch, you'd use an AtomicBoolean.

However, because of erasure, this won't work with WrappedEvent<A> and WrappedEvent<B> as the EventBus has no generic information available. You could subclass the wrapper like WrappedA extends WrappedEvent<A> {} and work with it. It's damn ugly.

Meaningfully extending the EventBus is hardly possible, if you don't want to sneak into its package. The easiest way would probably be forking the whole package and the adding a break after this line.

Upvotes: 0

Luciano van der Veekens
Luciano van der Veekens

Reputation: 6577

Events are routed to all registered subscribers as long as they match the event type.

It's in the Javadoc of EventBus:

Posting Events

To post an event, simply provide the event object to the post(Object) method. The EventBus instance will determine the type of event and route it to all registered listeners.

Events are routed based on their type — an event will be delivered to any subscriber for any type to which the event is assignable. This includes implemented interfaces, all superclasses, and all interfaces implemented by superclasses.

Upvotes: 3

Related Questions