use of org.jboss.weld.util.Observers in project core by weld.
the class ObserverNotifier method notifyAsyncObservers.
protected <T, U extends T> CompletionStage<U> notifyAsyncObservers(List<ObserverMethod<? super T>> observers, U event, EventMetadata metadata, Executor executor, NotificationOptions options) {
if (executor == null) {
executor = asyncEventExecutor;
}
if (observers.isEmpty()) {
return AsyncEventDeliveryStage.completed(event, executor);
}
// We should always initialize and validate all notification options first
final NotificationMode mode = initModeOption(options.get(WeldNotificationOptions.MODE));
final Long timeout = initTimeoutOption(options.get(WeldNotificationOptions.TIMEOUT));
final Consumer<Runnable> securityContextActionConsumer = securityServices.getSecurityContextAssociator();
final ObserverExceptionHandler exceptionHandler;
CompletableFuture<U> completableFuture;
if (observers.size() > 1 && NotificationMode.PARALLEL.equals(mode)) {
// Attempt to notify async observers in parallel
exceptionHandler = new CollectingExceptionHandler(new CopyOnWriteArrayList<>());
List<CompletableFuture<T>> completableFutures = new ArrayList<>(observers.size());
for (ObserverMethod<? super T> observer : observers) {
completableFutures.add(CompletableFuture.supplyAsync(createSupplier(securityContextActionConsumer, event, metadata, exceptionHandler, false, () -> {
notifyAsyncObserver(observer, event, metadata, exceptionHandler);
}), executor));
}
completableFuture = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[] {})).thenApply((ignoredVoid) -> {
handleExceptions(exceptionHandler);
return event;
});
} else {
// Async observers are notified serially in a single worker thread
exceptionHandler = new CollectingExceptionHandler();
completableFuture = CompletableFuture.supplyAsync(createSupplier(securityContextActionConsumer, event, metadata, exceptionHandler, true, () -> {
for (ObserverMethod<? super T> observer : observers) {
notifyAsyncObserver(observer, event, metadata, exceptionHandler);
}
}), executor);
}
// If NotificationOptionKeys.TIMEOUT is set, we will trigger the counter and use CompletableFuture.anyOf()
if (timeout != null) {
completableFuture = CompletableFuture.anyOf(completableFuture, startTimer(timeout)).thenApply((ignoredObject) -> event);
}
return new AsyncEventDeliveryStage<>(completableFuture, executor);
}
Aggregations