Search in sources :

Example 1 with CompletionException

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

the class CompletableFutureTest method testApplyToEither_exceptionalCompletion2.

public void testApplyToEither_exceptionalCompletion2() {
    for (ExecutionMode m : ExecutionMode.values()) for (boolean fFirst : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) {
        final CompletableFuture<Integer> f = new CompletableFuture<>();
        final CompletableFuture<Integer> g = new CompletableFuture<>();
        final CFException ex = new CFException();
        final IncFunction[] rs = new IncFunction[6];
        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
        // unspecified behavior - both source completions available
        try {
            assertEquals(inc(v1), h0.join());
            rs[0].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h0, ex);
            rs[0].assertNotInvoked();
        }
        try {
            assertEquals(inc(v1), h1.join());
            rs[1].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h1, ex);
            rs[1].assertNotInvoked();
        }
        try {
            assertEquals(inc(v1), h2.join());
            rs[2].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h2, ex);
            rs[2].assertNotInvoked();
        }
        try {
            assertEquals(inc(v1), h3.join());
            rs[3].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h3, ex);
            rs[3].assertNotInvoked();
        }
        checkCompletedNormally(f, v1);
        checkCompletedExceptionally(g, ex);
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) CompletionException(java8.util.concurrent.CompletionException)

Example 2 with CompletionException

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

the class CompletableFutureTest method testAcceptEither_exceptionalCompletion2.

public void testAcceptEither_exceptionalCompletion2() {
    for (ExecutionMode m : ExecutionMode.values()) for (boolean fFirst : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) {
        final CompletableFuture<Integer> f = new CompletableFuture<>();
        final CompletableFuture<Integer> g = new CompletableFuture<>();
        final CFException ex = new CFException();
        final NoopConsumer[] rs = new NoopConsumer[6];
        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
        // unspecified behavior - both source completions available
        try {
            assertNull(h0.join());
            rs[0].assertValue(v1);
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h0, ex);
            rs[0].assertNotInvoked();
        }
        try {
            assertNull(h1.join());
            rs[1].assertValue(v1);
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h1, ex);
            rs[1].assertNotInvoked();
        }
        try {
            assertNull(h2.join());
            rs[2].assertValue(v1);
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h2, ex);
            rs[2].assertNotInvoked();
        }
        try {
            assertNull(h3.join());
            rs[3].assertValue(v1);
        } catch (CompletionException ok) {
            checkCompletedWithWrappedException(h3, ex);
            rs[3].assertNotInvoked();
        }
        checkCompletedNormally(f, v1);
        checkCompletedExceptionally(g, ex);
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) CompletionException(java8.util.concurrent.CompletionException)

Example 3 with CompletionException

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

the class Basic method test.

private static void test(ExecutorService executor) throws Throwable {
    Thread.currentThread().setName("mainThread");
    // ----------------------------------------------------------------
    try {
        CompletableFuture<String> cf = supplyAsync(() -> "a test string");
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> "a test string", commonPool());
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> "a test string", executor);
        checkCompletedNormally(cf, cf.join());
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        });
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        }, commonPool());
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedExceptionally(cf);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf = runAsync(() -> {
        });
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
        }, commonPool());
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
        }, executor);
        checkCompletedNormally(cf, cf.join());
        cf = runAsync(() -> {
            throw new RuntimeException();
        });
        checkCompletedExceptionally(cf);
        cf = runAsync(() -> {
            throw new RuntimeException();
        }, commonPool());
        checkCompletedExceptionally(cf);
        cf = runAsync(() -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedExceptionally(cf);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        final Phaser phaser = new Phaser(1);
        final int phase = phaser.getPhase();
        CompletableFuture<Integer> cf;
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase);
            return 1;
        });
        cf.complete(2);
        phaser.arrive();
        checkCompletedNormally(cf, 2);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 1);
            return 1;
        });
        cf.completeExceptionally(new Throwable());
        phaser.arrive();
        checkCompletedExceptionally(cf);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 2);
            return 1;
        });
        cf.cancel(true);
        phaser.arrive();
        checkCompletedExceptionally(cf, true);
        cf = supplyAsync(() -> {
            phaser.awaitAdvance(phase + 3);
            return 1;
        });
        check(cf.getNow(2) == 2);
        phaser.arrive();
        checkCompletedNormally(cf, 1);
        check(cf.getNow(2) == 1);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApply(x -> x.equals("a test string") ? 1 : 0);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApplyAsync(x -> x.equals("a test string") ? 1 : 0);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenApplyAsync(x -> x.equals("a test string") ? 1 : 0, executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, 1);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApply(x -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApplyAsync(x -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenApplyAsync(x -> 0, executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf2;
        int before = atomicInt.get();
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAccept(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        });
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAcceptAsync(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        });
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenAcceptAsync(x -> {
            if (x.equals("a test string")) {
                atomicInt.incrementAndGet();
                return;
            }
            throw new RuntimeException();
        }, executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAccept(x -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAcceptAsync(x -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenAcceptAsync(x -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf2;
        int before = atomicInt.get();
        CompletableFuture<String> cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRun(() -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> "a test string");
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet(), executor);
        checkCompletedNormally(cf1, "a test string");
        checkCompletedNormally(cf2, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRun(() -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenRunAsync(() -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf3;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombine(cf2, (x, y) -> x + y);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> x + y);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> x + y, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenCombine(cf2, (x, y) -> 0);
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 1);
        checkCompletedExceptionally(cf3);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> 0);
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenCombineAsync(cf2, (x, y) -> 0, executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBoth(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> {
            check(x + y == 2);
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 1);
        cf3 = cf1.thenAcceptBoth(cf2, (x, y) -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 1);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.thenAcceptBothAsync(cf2, (x, y) -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 1);
        cf3 = cf1.runAfterBoth(cf2, () -> {
            check(cf1.isDone());
            check(cf2.isDone());
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cfa = supplyAsync(() -> 1);
        CompletableFuture<Integer> cfb = supplyAsync(() -> 1);
        cf3 = cfa.runAfterBothAsync(cfb, () -> {
            check(cfa.isDone());
            check(cfb.isDone());
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cfa, 1);
        checkCompletedNormally(cfb, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cfx = supplyAsync(() -> 1);
        CompletableFuture<Integer> cfy = supplyAsync(() -> 1);
        cf3 = cfy.runAfterBothAsync(cfx, () -> {
            check(cfx.isDone());
            check(cfy.isDone());
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cfx, 1);
        checkCompletedNormally(cfy, 1);
        checkCompletedNormally(cf3, null);
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        CompletableFuture<Integer> cf4 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        CompletableFuture<Integer> cf5 = supplyAsync(() -> 1);
        cf3 = cf5.runAfterBothAsync(cf4, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf4);
        checkCompletedNormally(cf5, 1);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        before = atomicInt.get();
        cf4 = supplyAsync(() -> 1);
        cf5 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf5.runAfterBothAsync(cf4, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf4, 1);
        checkCompletedExceptionally(cf5);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
        before = atomicInt.get();
        cf4 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf5 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf5.runAfterBoth(cf4, () -> atomicInt.incrementAndGet());
        checkCompletedExceptionally(cf4);
        checkCompletedExceptionally(cf5);
        checkCompletedExceptionally(cf3);
        check(atomicInt.get() == before);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf3;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        });
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        });
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            return x;
        }, executor);
        checkCompletedNormally(cf3, new Object[] { 1, 2 });
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 2);
            return x;
        });
        try {
            check(cf3.join() == 2);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1);
            return x;
        });
        try {
            check(cf3.join() == 1);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            fail();
            return x;
        });
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        final Phaser cf3Done = new Phaser(2);
        cf1 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 1;
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.applyToEither(cf2, x -> {
            check(x == 2);
            return x;
        });
        checkCompletedNormally(cf3, 2);
        checkCompletedNormally(cf2, 2);
        check(!cf1.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf3, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 2;
        });
        cf3 = cf1.applyToEitherAsync(cf2, x -> {
            check(x == 1);
            return x;
        });
        checkCompletedNormally(cf3, 1);
        checkCompletedNormally(cf1, 1);
        check(!cf2.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf2, 2);
        checkCompletedNormally(cf3, 1);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEither(cf2, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEitherAsync(cf2, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        });
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> 2);
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 1 || x == 2);
            atomicInt.incrementAndGet();
        }, executor);
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 2);
        }, executor);
        try {
            check(cf3.join() == null);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            check(x == 1);
        });
        try {
            check(cf3.join() == null);
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.acceptEitherAsync(cf1, x -> {
            fail();
        });
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        final Phaser cf3Done = new Phaser(2);
        cf1 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 1;
        });
        cf2 = supplyAsync(() -> 2);
        cf3 = cf1.acceptEither(cf2, x -> {
            check(x == 2);
        });
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf2, 2);
        check(!cf1.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf3, null);
        cf1 = supplyAsync(() -> 1);
        cf2 = supplyAsync(() -> {
            cf3Done.arriveAndAwaitAdvance();
            return 2;
        });
        cf3 = cf1.acceptEitherAsync(cf2, x -> {
            check(x == 1);
        });
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf1, 1);
        check(!cf2.isDone());
        cf3Done.arrive();
        checkCompletedNormally(cf2, 2);
        checkCompletedNormally(cf3, null);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Void> cf3;
        int before = atomicInt.get();
        CompletableFuture<Void> cf1 = runAsync(() -> {
        });
        CompletableFuture<Void> cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEither(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf2.runAfterEitherAsync(cf1, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedNormally(cf3, null);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == (before + 1));
        before = atomicInt.get();
        cf1 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = runAsync(() -> {
        });
        cf3 = cf2.runAfterEither(cf1, () -> atomicInt.incrementAndGet());
        try {
            check(cf3.join() == null);
            check(atomicInt.get() == (before + 1));
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        try {
            check(cf3.join() == null);
            check(atomicInt.get() == (before + 1));
        } catch (CompletionException x) {
            pass();
        }
        check(cf3.isDone());
        check(cf1.isDone() || cf2.isDone());
        before = atomicInt.get();
        cf1 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = runAsync(() -> {
            throw new RuntimeException();
        });
        cf3 = cf2.runAfterEitherAsync(cf1, () -> atomicInt.incrementAndGet(), executor);
        checkCompletedExceptionally(cf3);
        check(cf1.isDone() || cf2.isDone());
        check(atomicInt.get() == before);
        final Phaser cf3Done = new Phaser(2);
        before = atomicInt.get();
        cf1 = runAsync(() -> cf3Done.arriveAndAwaitAdvance());
        cf2 = runAsync(() -> {
        });
        cf3 = cf1.runAfterEither(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf2, null);
        check(!cf1.isDone());
        check(atomicInt.get() == (before + 1));
        cf3Done.arrive();
        checkCompletedNormally(cf1, null);
        checkCompletedNormally(cf3, null);
        before = atomicInt.get();
        cf1 = runAsync(() -> {
        });
        cf2 = runAsync(() -> cf3Done.arriveAndAwaitAdvance());
        cf3 = cf1.runAfterEitherAsync(cf2, () -> atomicInt.incrementAndGet());
        checkCompletedNormally(cf3, null);
        checkCompletedNormally(cf1, null);
        check(!cf2.isDone());
        check(atomicInt.get() == (before + 1));
        cf3Done.arrive();
        checkCompletedNormally(cf2, null);
        checkCompletedNormally(cf3, null);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenCompose(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            check(x == 1);
            return CompletableFuture.completedFuture(2);
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        int before = atomicInt.get();
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenCompose(x -> {
            atomicInt.incrementAndGet();
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> {
            throw new RuntimeException();
        });
        cf2 = cf1.thenComposeAsync(x -> {
            atomicInt.incrementAndGet();
            return CompletableFuture.completedFuture(2);
        });
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(atomicInt.get() == before);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.thenComposeAsync(x -> {
            throw new RuntimeException();
        }, executor);
        checkCompletedNormally(cf1, 1);
        checkCompletedExceptionally(cf2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Object> cf3;
        for (int k = 0; k < 10; k++) {
            CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
            CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
            cf3 = CompletableFuture.anyOf(cf1, cf2);
            checkCompletedNormally(cf3, new Object[] { 1, 2 });
            check(cf1.isDone() || cf2.isDone());
        }
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<?> cf3;
        for (int k = 0; k < 10; k++) {
            CompletableFuture<Integer>[] cfs = (CompletableFuture<Integer>[]) Array.newInstance(CompletableFuture.class, 10);
            for (int j = 0; j < 10; j++) {
                final int v = j;
                cfs[j] = supplyAsync(() -> v);
            }
            cf3 = CompletableFuture.allOf(cfs);
            for (int j = 0; j < 10; j++) checkCompletedNormally(cfs[j], j);
            checkCompletedNormally(cf3, null);
        }
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.exceptionally(t -> {
            fail("function should never be called");
            return 2;
        });
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        final RuntimeException t = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw t;
        });
        cf2 = cf1.exceptionally(x -> {
            check(x.getCause() == t);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.handle((x, t) -> x + 1);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        final RuntimeException ex = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.handle((x, t) -> {
            check(t.getCause() == ex);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.handleAsync((x, t) -> x + 1);
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 2);
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.handleAsync((x, t) -> {
            check(t.getCause() == ex);
            return 2;
        });
        checkCompletedExceptionally(cf1);
        checkCompletedNormally(cf2, 2);
    } catch (Throwable t) {
        unexpected(t);
    }
    // ----------------------------------------------------------------
    try {
        AtomicInteger count = new AtomicInteger();
        CompletableFuture<Integer> cf2;
        CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
        cf2 = cf1.whenComplete((x, t) -> count.getAndIncrement());
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        check(count.get() == 1, "action count should be incremented");
        final RuntimeException ex = new RuntimeException();
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.whenComplete((x, t) -> count.getAndIncrement());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(count.get() == 2, "action count should be incremented");
        cf1 = supplyAsync(() -> 1);
        cf2 = cf1.whenCompleteAsync((x, t) -> count.getAndIncrement());
        checkCompletedNormally(cf1, 1);
        checkCompletedNormally(cf2, 1);
        check(count.get() == 3, "action count should be incremented");
        cf1 = supplyAsync(() -> {
            throw ex;
        });
        cf2 = cf1.whenCompleteAsync((x, t) -> count.getAndIncrement());
        checkCompletedExceptionally(cf1);
        checkCompletedExceptionally(cf2);
        check(count.get() == 4, "action count should be incremented");
    } catch (Throwable t) {
        unexpected(t);
    }
}
Also used : ForkJoinPool.commonPool(java8.util.concurrent.ForkJoinPool.commonPool) CompletableFuture.supplyAsync(java8.util.concurrent.CompletableFuture.supplyAsync) Array(java.lang.reflect.Array) CancellationException(java.util.concurrent.CancellationException) Test(org.testng.annotations.Test) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) Executors(java.util.concurrent.Executors) ExecutionException(java.util.concurrent.ExecutionException) Phaser(java8.util.concurrent.Phaser) Utils(jdk.testlibrary.Utils) CompletableFuture(java8.util.concurrent.CompletableFuture) CompletableFuture.runAsync(java8.util.concurrent.CompletableFuture.runAsync) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletionException(java8.util.concurrent.CompletionException) SECONDS(java.util.concurrent.TimeUnit.SECONDS) ExecutorService(java.util.concurrent.ExecutorService) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletionException(java8.util.concurrent.CompletionException) Phaser(java8.util.concurrent.Phaser)

Example 4 with CompletionException

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

the class ConcurrentAssociateTest method testOnce.

private static void testOnce(final String desc, final BiConsumer<ConcurrentMap<Object, Object>, Object> associator) {
    final ConcurrentHashMap<Object, Object> m = new ConcurrentHashMap<Object, Object>();
    final CountDownLatch s = new CountDownLatch(1);
    final Supplier<Runnable> putter = new Supplier<Runnable>() {

        @Override
        public Runnable get() {
            return new Runnable() {

                @Override
                public void run() {
                    try {
                        s.await();
                    } catch (InterruptedException e) {
                    }
                    for (int i = 0; i < N; i++) {
                        Object o = new X();
                        associator.accept(m, o);
                        if (!m.containsKey(o)) {
                            throw new AssociationFailure(desc + " failed: entry does not exist");
                        }
                    }
                }
            };
        }
    };
    Stream<CompletableFuture<Void>> putters = IntStreams.range(0, availableProcessors).mapToObj(new IntFunction<Runnable>() {

        public Runnable apply(int i) {
            return putter.get();
        }
    }).map(new Function<Runnable, CompletableFuture<Void>>() {

        @Override
        public CompletableFuture<Void> apply(Runnable runnable) {
            return CompletableFuture.runAsync(runnable);
        }
    });
    CompletableFuture<Void> all = CompletableFuture.allOf(putters.toArray(new IntFunction<CompletableFuture<Void>[]>() {

        @Override
        @SuppressWarnings("unchecked")
        public CompletableFuture<Void>[] apply(int size) {
            return (CompletableFuture<Void>[]) new CompletableFuture[size];
        }
    }));
    // Trigger the runners to start
    s.countDown();
    try {
        all.join();
    } catch (CompletionException e) {
        Throwable t = e.getCause();
        if (t instanceof AssociationFailure) {
            throw (AssociationFailure) t;
        } else {
            throw e;
        }
    }
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) CompletableFuture(java8.util.concurrent.CompletableFuture) IntFunction(java8.util.function.IntFunction) CompletionException(java8.util.concurrent.CompletionException) Supplier(java8.util.function.Supplier) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 5 with CompletionException

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

the class CompletableFutureTest method testApplyToEither_sourceCancelled.

/**
 * applyToEither result completes exceptionally if either source cancelled
 */
public void testApplyToEither_sourceCancelled() {
    for (ExecutionMode m : ExecutionMode.values()) for (boolean mayInterruptIfRunning : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) {
        final CompletableFuture<Integer> f = new CompletableFuture<>();
        final CompletableFuture<Integer> g = new CompletableFuture<>();
        final IncFunction[] rs = new IncFunction[6];
        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
        checkIncomplete(h0);
        checkIncomplete(h1);
        rs[0].assertNotInvoked();
        rs[1].assertNotInvoked();
        f.cancel(mayInterruptIfRunning);
        checkCompletedWithWrappedCancellationException(h0);
        checkCompletedWithWrappedCancellationException(h1);
        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
        checkCompletedWithWrappedCancellationException(h2);
        checkCompletedWithWrappedCancellationException(h3);
        g.complete(v1);
        // unspecified behavior - both source completions available
        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
        try {
            assertEquals(inc(v1), h4.join());
            rs[4].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedCancellationException(h4);
            rs[4].assertNotInvoked();
        }
        try {
            assertEquals(inc(v1), h5.join());
            rs[5].assertValue(inc(v1));
        } catch (CompletionException ok) {
            checkCompletedWithWrappedCancellationException(h5);
            rs[5].assertNotInvoked();
        }
        checkCancelled(f);
        checkCompletedNormally(g, v1);
        checkCompletedWithWrappedCancellationException(h0);
        checkCompletedWithWrappedCancellationException(h1);
        checkCompletedWithWrappedCancellationException(h2);
        checkCompletedWithWrappedCancellationException(h3);
        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CompletableFuture(java8.util.concurrent.CompletableFuture) CompletionException(java8.util.concurrent.CompletionException)

Aggregations

CompletableFuture (java8.util.concurrent.CompletableFuture)8 CompletionException (java8.util.concurrent.CompletionException)8 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 Array (java.lang.reflect.Array)1 CancellationException (java.util.concurrent.CancellationException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutionException (java.util.concurrent.ExecutionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 MILLISECONDS (java.util.concurrent.TimeUnit.MILLISECONDS)1 SECONDS (java.util.concurrent.TimeUnit.SECONDS)1 CompletableFuture.runAsync (java8.util.concurrent.CompletableFuture.runAsync)1 CompletableFuture.supplyAsync (java8.util.concurrent.CompletableFuture.supplyAsync)1 ForkJoinPool.commonPool (java8.util.concurrent.ForkJoinPool.commonPool)1 Phaser (java8.util.concurrent.Phaser)1 IntFunction (java8.util.function.IntFunction)1 Supplier (java8.util.function.Supplier)1 Utils (jdk.testlibrary.Utils)1 Test (org.testng.annotations.Test)1