Search in sources :

Example 1 with NotificationOptions

use of javax.enterprise.event.NotificationOptions 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);
}
Also used : ServiceRegistry(org.jboss.weld.bootstrap.api.ServiceRegistry) WeldNotificationOptions(org.jboss.weld.events.WeldNotificationOptions) EventLogger(org.jboss.weld.logging.EventLogger) Reflections(org.jboss.weld.util.reflection.Reflections) SharedObjectCache(org.jboss.weld.resources.SharedObjectCache) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) ObserverMethod(javax.enterprise.inject.spi.ObserverMethod) Types(org.jboss.weld.util.Types) Reflections.cast(org.jboss.weld.util.reflection.Reflections.cast) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ComputingCache(org.jboss.weld.util.cache.ComputingCache) QualifierInstance(org.jboss.weld.resolution.QualifierInstance) LazyValueHolder(org.jboss.weld.util.LazyValueHolder) NotificationOptions(javax.enterprise.event.NotificationOptions) SecurityServices(org.jboss.weld.security.spi.SecurityServices) ExecutorServices(org.jboss.weld.manager.api.ExecutorServices) Observers(org.jboss.weld.util.Observers) EventMetadata(javax.enterprise.inject.spi.EventMetadata) UtilLogger(org.jboss.weld.logging.UtilLogger) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) RequestContext(org.jboss.weld.context.RequestContext) LinkedList(java.util.LinkedList) ResolvableBuilder(org.jboss.weld.resolution.ResolvableBuilder) ThreadLocalStackReference(org.jboss.weld.injection.ThreadLocalStack.ThreadLocalStackReference) NotificationMode(org.jboss.weld.events.WeldNotificationOptions.NotificationMode) Executor(java.util.concurrent.Executor) UnboundLiteral(org.jboss.weld.context.unbound.UnboundLiteral) Set(java.util.Set) ObserverException(javax.enterprise.event.ObserverException) CompletionException(java.util.concurrent.CompletionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Resolvable(org.jboss.weld.resolution.Resolvable) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) ComputingCacheBuilder(org.jboss.weld.util.cache.ComputingCacheBuilder) Type(java.lang.reflect.Type) ForkJoinPool(java.util.concurrent.ForkJoinPool) Annotation(java.lang.annotation.Annotation) Collections(java.util.Collections) TypeSafeObserverResolver(org.jboss.weld.resolution.TypeSafeObserverResolver) Container(org.jboss.weld.Container) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) NotificationMode(org.jboss.weld.events.WeldNotificationOptions.NotificationMode) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompletableFuture(java.util.concurrent.CompletableFuture) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 2 with NotificationOptions

use of javax.enterprise.event.NotificationOptions in project core by weld.

the class NotificationTimeoutTest method testMultipleObserverParallelNotificationTimeout.

@Test
public void testMultipleObserverParallelNotificationTimeout() throws InterruptedException {
    SUCCESSION_OF_EVENTS.clear();
    try (WeldContainer container = new Weld().initialize()) {
        BlockingQueue<Throwable> synchronizer = new LinkedBlockingQueue<>();
        CountDownLatch countdown = new CountDownLatch(2);
        NotificationOptions options = NotificationOptions.builder().set(WeldNotificationOptions.TIMEOUT, "2000").set(WeldNotificationOptions.MODE, WeldNotificationOptions.NotificationMode.PARALLEL).build();
        container.event().select(CountDownLatch.class).fireAsync(countdown, options).exceptionally((Throwable t) -> {
            // handle TimeoutException we got here
            SUCCESSION_OF_EVENTS.add("Timeout");
            synchronizer.add(t);
            return null;
        });
        Throwable fromSynchronizer = synchronizer.poll(5, TimeUnit.SECONDS);
        Assert.assertNotNull(fromSynchronizer);
        Assert.assertTrue(fromSynchronizer.getCause().toString().contains(TimeoutException.class.getSimpleName()));
        // wait for the observers to finish their jobs
        countdown.await();
        // with parallel execution, we can only assert that all observers were notified (the order might differ)
        Assert.assertTrue(SUCCESSION_OF_EVENTS.size() == 3);
        Assert.assertTrue(SUCCESSION_OF_EVENTS.containsAll(getExpectedListOfEvents()));
    }
}
Also used : WeldNotificationOptions(org.jboss.weld.events.WeldNotificationOptions) NotificationOptions(javax.enterprise.event.NotificationOptions) WeldContainer(org.jboss.weld.environment.se.WeldContainer) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) CountDownLatch(java.util.concurrent.CountDownLatch) Weld(org.jboss.weld.environment.se.Weld) Test(org.junit.Test)

Aggregations

NotificationOptions (javax.enterprise.event.NotificationOptions)2 WeldNotificationOptions (org.jboss.weld.events.WeldNotificationOptions)2 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 Annotation (java.lang.annotation.Annotation)1 Type (java.lang.reflect.Type)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Set (java.util.Set)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CompletionException (java.util.concurrent.CompletionException)1 CompletionStage (java.util.concurrent.CompletionStage)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Executor (java.util.concurrent.Executor)1 ForkJoinPool (java.util.concurrent.ForkJoinPool)1 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 TimeUnit (java.util.concurrent.TimeUnit)1