}
}
@Override
public void publishIffNotDead(EventCreator creator, Class<?>... eventTypes) {
Stopwatch start = stats.conditionalPublishStats.start();
try {
Map<Class<?>, Set<EventConsumer>> interestedConsumersByType = new HashMap<Class<?>, Set<EventConsumer>>();
for (Class<?> eventType : eventTypes) {
for (Class<?> anEventSubType : getAllTypesForAnEventType(eventType)) {
Set<EventConsumer> eventConsumers = consumersByEventType.get(anEventSubType);
if (!eventConsumers.isEmpty()) {
/*
* Since any change in the underlying consumers get reflected in this set, we get the benefit of any changes
* to the consumers after this check being reflected when we invoke these consumers.
* We add the evenType to the map and not the subType as the event creator is only aware of the high
* level types & not the entire hierarchy.
*/
interestedConsumersByType.put(eventType, eventConsumers);
}
}
}
if (interestedConsumersByType.isEmpty()) {
LOGGER.debug(String.format("Skipping publishing of events types %s as there are no interested listeners.",
Arrays.toString(eventTypes)));
return;
}
List events = creator.createEvent(interestedConsumersByType.keySet());
if (null == events) {
LOGGER.debug(String.format("No events created by event creator for event types %s",
interestedConsumersByType.keySet()));
return;
}
for (Object event : events) {
if (!applyEventLevelFilters(event)) {
continue;
}
Set<EventConsumer> eventConsumers = interestedConsumersByType.get(event.getClass());
for (EventConsumer eventConsumer : eventConsumers) {
eventConsumer.enqueue(event);
}
}
} catch (Throwable th) {
LOGGER.error("Error occured while publishing event. Swallowing the error to avoid publisher from failing.", th);
stats.conditionalPublishErrors.increment();
} finally {
start.stop();
}
}