Search in sources :

Example 11 with CompletableFuture

use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testWhenComplete_normalCompletion.

/**
 * whenComplete action executes on normal completion, propagating
 * source result.
 */
public void testWhenComplete_normalCompletion() {
    for (ExecutionMode m : ExecutionMode.values()) for (boolean createIncomplete : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) {
        final AtomicInteger a = new AtomicInteger(0);
        final CompletableFuture<Integer> f = new CompletableFuture<>();
        if (!createIncomplete)
            assertTrue(f.complete(v1));
        final CompletableFuture<Integer> g = m.whenComplete(f, (Integer result, Throwable t) -> {
            m.checkExecutionMode();
            threadAssertSame(result, v1);
            threadAssertNull(t);
            a.getAndIncrement();
        });
        if (createIncomplete)
            assertTrue(f.complete(v1));
        checkCompletedNormally(g, v1);
        checkCompletedNormally(f, v1);
        assertEquals(1, a.get());
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 12 with CompletableFuture

use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testMinimalCompletionStage_minimality.

/**
 * Minimal completion stages throw UOE for most non-CompletionStage methods
 */
public void testMinimalCompletionStage_minimality() {
    if (!testImplementationDetails)
        return;
    Function<Method, String> toSignature = method -> method.getName() + Arrays.toString(method.getParameterTypes());
    Predicate<Method> isNotStatic = method -> (method.getModifiers() & Modifier.STATIC) == 0;
    List<Method> minimalMethods = RefStreams.of(Object.class, CompletionStage.class).flatMap(klazz -> RefStreams.of(klazz.getMethods())).filter(isNotStatic).collect(Collectors.toList());
    // Methods from CompletableFuture permitted NOT to throw UOE
    String[] signatureWhitelist = { "newIncompleteFuture[]", "defaultExecutor[]", "minimalCompletionStage[]", "copy[]" };
    Set<String> permittedMethodSignatures = RefStreams.concat(StreamSupport.stream(minimalMethods).map(toSignature), RefStreams.of(signatureWhitelist)).collect(Collectors.toSet());
    List<Method> allMethods = RefStreams.of(CompletableFuture.class.getMethods()).filter(isNotStatic).filter(method -> !permittedMethodSignatures.contains(toSignature.apply(method))).collect(Collectors.toList());
    List<CompletionStage<Integer>> stages = new ArrayList<CompletionStage<Integer>>();
    CompletionStage<Integer> min = new CompletableFuture<Integer>().minimalCompletionStage();
    stages.add(min);
    stages.add(min.thenApply(x -> x));
    stages.add(CompletableFuture.completedStage(1));
    stages.add(CompletableFuture.failedStage(new CFException()));
    List<Method> bugs = new ArrayList<>();
    for (Method method : allMethods) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object[] args = new Object[parameterTypes.length];
        // Manufacture boxed primitives for primitive params
        for (int i = 0; i < args.length; i++) {
            Class<?> type = parameterTypes[i];
            if (type == boolean.class)
                args[i] = false;
            else if (type == int.class)
                args[i] = 0;
            else if (type == long.class)
                args[i] = 0L;
        }
        for (CompletionStage<Integer> stage : stages) {
            try {
                method.invoke(stage, args);
                bugs.add(method);
            } catch (java.lang.reflect.InvocationTargetException expected) {
                if (!(expected.getCause() instanceof UnsupportedOperationException)) {
                    bugs.add(method);
                // expected.getCause().printStackTrace();
                }
            } catch (Exception bad) {
                throw new Error(bad);
            }
        }
    }
    if (!bugs.isEmpty())
        throw new Error("Methods did not throw UOE: " + bugs);
}
Also used : Arrays(java.util.Arrays) Test(junit.framework.Test) TimeoutException(java.util.concurrent.TimeoutException) Callable(java.util.concurrent.Callable) CompletableFuture.completedFuture(java8.util.concurrent.CompletableFuture.completedFuture) Predicate(java8.util.function.Predicate) AtomicReference(java.util.concurrent.atomic.AtomicReference) CompletableFuture.failedFuture(java8.util.concurrent.CompletableFuture.failedFuture) Function(java8.util.function.Function) ArrayList(java.util.ArrayList) TestSuite(junit.framework.TestSuite) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) BiFunction(java8.util.function.BiFunction) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Consumer(java8.util.function.Consumer) ForkJoinPool(java8.util.concurrent.ForkJoinPool) Method(java.lang.reflect.Method) CompletionStage(java8.util.concurrent.CompletionStage) Objects(java8.util.Objects) CancellationException(java.util.concurrent.CancellationException) Executor(java.util.concurrent.Executor) ForkJoinTask(java8.util.concurrent.ForkJoinTask) Set(java.util.Set) Collectors(java8.util.stream.Collectors) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) StreamSupport(java8.util.stream.StreamSupport) Supplier(java8.util.function.Supplier) ExecutionException(java.util.concurrent.ExecutionException) List(java.util.List) CompletableFuture(java8.util.concurrent.CompletableFuture) BiConsumer(java8.util.function.BiConsumer) RefStreams(java8.util.stream.RefStreams) Modifier(java.lang.reflect.Modifier) CompletionException(java8.util.concurrent.CompletionException) SECONDS(java.util.concurrent.TimeUnit.SECONDS) ArrayList(java.util.ArrayList) CompletionStage(java8.util.concurrent.CompletionStage) Method(java.lang.reflect.Method) TimeoutException(java.util.concurrent.TimeoutException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) CancellationException(java.util.concurrent.CancellationException) ExecutionException(java.util.concurrent.ExecutionException) CompletionException(java8.util.concurrent.CompletionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 13 with CompletableFuture

use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testExceptionally_exceptionalCompletionActionFailed.

/**
 * If an "exceptionally action" throws an exception, it completes
 * exceptionally with that exception
 */
public void testExceptionally_exceptionalCompletionActionFailed() {
    for (boolean createIncomplete : new boolean[] { true, false }) {
        final AtomicInteger a = new AtomicInteger(0);
        final CFException ex1 = new CFException();
        final CFException ex2 = new CFException();
        final CompletableFuture<Integer> f = new CompletableFuture<>();
        if (!createIncomplete)
            f.completeExceptionally(ex1);
        final CompletableFuture<Integer> g = f.exceptionally((Throwable t) -> {
            ExecutionMode.SYNC.checkExecutionMode();
            threadAssertSame(t, ex1);
            a.getAndIncrement();
            throw ex2;
        });
        if (createIncomplete)
            f.completeExceptionally(ex1);
        checkCompletedWithWrappedException(g, ex2);
        checkCompletedExceptionally(f, ex1);
        assertEquals(1, a.get());
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 14 with CompletableFuture

use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testMinimalCompletionStage.

/**
 * minimalCompletionStage returns a CompletableFuture that is
 * completed normally, with the same value, when source is.
 */
public void testMinimalCompletionStage() {
    CompletableFuture<Integer> f = new CompletableFuture<>();
    CompletionStage<Integer> g = f.minimalCompletionStage();
    AtomicInteger x = new AtomicInteger(0);
    AtomicReference<Throwable> r = new AtomicReference<>();
    checkIncomplete(f);
    g.whenComplete((v, e) -> {
        if (e != null)
            r.set(e);
        else
            x.set(v);
    });
    f.complete(1);
    checkCompletedNormally(f, 1);
    assertEquals(x.get(), 1);
    assertNull(r.get());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReference(java.util.concurrent.atomic.AtomicReference)

Example 15 with CompletableFuture

use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.

the class CompletableFutureTest method testManyDependents.

/**
 * A single CompletableFuture with many dependents.
 * A demo of scalability - runtime is O(n).
 */
public void testManyDependents() throws Throwable {
    final int n = expensiveTests ? 1_000_000 : 10;
    final CompletableFuture<Void> head = new CompletableFuture<>();
    final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void) null);
    final AtomicInteger count = new AtomicInteger(0);
    for (int i = 0; i < n; i++) {
        head.thenRun(() -> count.getAndIncrement());
        head.thenAccept(x -> count.getAndIncrement());
        head.thenApply(x -> count.getAndIncrement());
        head.runAfterBoth(complete, () -> count.getAndIncrement());
        head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
        head.thenCombine(complete, (x, y) -> count.getAndIncrement());
        complete.runAfterBoth(head, () -> count.getAndIncrement());
        complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
        complete.thenCombine(head, (x, y) -> count.getAndIncrement());
        head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
        head.acceptEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
        head.applyToEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
        new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
        new CompletableFuture<Void>().acceptEither(head, x -> count.getAndIncrement());
        new CompletableFuture<Void>().applyToEither(head, x -> count.getAndIncrement());
    }
    head.complete(null);
    assertEquals(5 * 3 * n, count.get());
}
Also used : CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Aggregations

CompletableFuture (java8.util.concurrent.CompletableFuture)44 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)41 CompletionException (java8.util.concurrent.CompletionException)11 CancellationException (java.util.concurrent.CancellationException)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 Set (java.util.Set)4 ExecutionException (java.util.concurrent.ExecutionException)4 Executor (java.util.concurrent.Executor)4 MILLISECONDS (java.util.concurrent.TimeUnit.MILLISECONDS)4 SECONDS (java.util.concurrent.TimeUnit.SECONDS)4 CompletionStage (java8.util.concurrent.CompletionStage)4 Supplier (java8.util.function.Supplier)4 Method (java.lang.reflect.Method)3 Modifier (java.lang.reflect.Modifier)3 Arrays (java.util.Arrays)3 Callable (java.util.concurrent.Callable)3 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)3 TimeoutException (java.util.concurrent.TimeoutException)3