org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException Java Examples

The following examples show how to use org.eclipse.microprofile.faulttolerance.exceptions.BulkheadException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DisableAnnotationOnClassEnableOnMethodTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    
    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    
    try {
        disableClient.waitForBulkheadExecutions(2);
        
        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the method, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();
        
        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #2
Source File: BulkheadAsynchRetryTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 *
 * Tests overloading the Retries by firing lots of work at a full Class
 * bulkhead
 * @throws InterruptedException when interrupted
 */
@Test
public void testBulkheadClassAsynchronous55RetryOverload() throws InterruptedException {
    int iterations = 1000;
    int maxSimultaneousWorkers = 5;
    TestData td = new TestData();

    Future[] results = loop(iterations, rrClassBean, maxSimultaneousWorkers, iterations, td);

    int failures = 0;
    for (Future result : results) {
        try {
            result.get();
        }
        catch (ExecutionException e) {
            if (e.getCause() instanceof BulkheadException) {
                failures++;
            }
            else {
                fail("Unexpected non-bulkhead exception thrown", e);
            }
        }
    }
    assertThat("Failure count should be non-zero", failures, greaterThan(0));
}
 
Example #3
Source File: BulkheadAsynchRetryTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Tests overloading the Retries by firing lots of work at a full Method
 * bulkhead
 *
 * @throws InterruptedException when interrupted
 */
@Test
public void testBulkheadMethodAsynchronous55RetryOverload() throws InterruptedException {
    int iterations = 1000;
    int maxSimultaneousWorkers = 5;
    TestData td = new TestData();

    Future[] results = loop(iterations, rrMethodBean, maxSimultaneousWorkers, 0, td);

    int failures = 0;
    for (Future result : results) {
        try {
            result.get();
        }
        catch (ExecutionException e) {
            if (e.getCause() instanceof BulkheadException) {
                failures++;
            }
            else {
                fail("Unexpected non-bulkhead exception thrown", e);
            }
        }
    }
    assertThat("Failure count should be non-zero", failures, greaterThan(0));
}
 
Example #4
Source File: BulkheadTest.java    From smallrye-fault-tolerance with Apache License 2.0 6 votes vote down vote up
@Test
public void testWaitingQueue(PingService pingService) throws InterruptedException, ExecutionException {
    int loop = QUEUE_SIZE * 2;
    CountDownLatch startLatch = new CountDownLatch(QUEUE_SIZE);
    CountDownLatch endLatch = new CountDownLatch(1);
    List<Future<String>> futures = new ArrayList<>();
    for (int i = 0; i < loop; i++) {
        futures.add(pingService.ping(startLatch, endLatch));
    }
    assertTrue(startLatch.await(5000L, TimeUnit.MILLISECONDS));
    Thread.sleep(500L);
    // Next invocation should not make it due to BulkheadException
    try {
        pingService.ping(null, null).get();
        fail("The call finished successfully but BulkheadException was expected to be thrown");
    } catch (ExecutionException e) {
        assertTrue(e.getCause() instanceof BulkheadException);
    }
    endLatch.countDown();
    for (int i = 0; i < loop; i++) {
        assertFalse(futures.get(i).isCancelled());
        assertEquals("the content check failed for future: " + futures.get(i), "pong", futures.get(i).get());
    }
}
 
Example #5
Source File: DisableAnnotationGloballyEnableOnClassTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    
    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    
    try {
        disableClient.waitForBulkheadExecutions(2);
        
        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the class, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();
        
        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #6
Source File: DisableAnnotationGloballyEnableOnMethodTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 *
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    
    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    
    try {
        disableClient.waitForBulkheadExecutions(2);
        
        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the method, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();
        
        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #7
Source File: DisableFTEnableOnClassTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);

    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));

    try {
        disableClient.waitForBulkheadExecutions(2);

        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the class, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();

        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #8
Source File: DisableFTEnableOnMethodTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);

    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));

    try {
        disableClient.waitForBulkheadExecutions(2);

        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the method, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();

        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #9
Source File: DisableFTEnableGloballyTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
/**
 * Test whether Bulkhead is enabled on {@code waitWithBulkhead()}
 *
 * @throws InterruptedException interrupted
 * @throws ExecutionException task was aborted
 */
@Test
public void testBulkhead() throws ExecutionException, InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(10);

    // Start two executions at once
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> result1 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));
    Future<?> result2 = executor.submit(() -> disableClient.waitWithBulkhead(waitingFuture));

    try {
        disableClient.waitForBulkheadExecutions(2);

        // Try to start a third execution. This would throw a BulkheadException if Bulkhead is enabled.
        // Bulkhead is enabled on the class, so expect exception
        Assert.assertThrows(BulkheadException.class, () -> disableClient.waitWithBulkhead(CompletableFuture.completedFuture(null)));
    }
    finally {
        // Clean up executor and first two executions
        executor.shutdown();

        waitingFuture.complete(null);
        result1.get();
        result2.get();
    }
}
 
Example #10
Source File: FaultToleranceTest.java    From quarkus with Apache License 2.0 6 votes vote down vote up
@Test
public void testBulkhead() throws InterruptedException {
    AtomicBoolean success = new AtomicBoolean(true);
    AtomicBoolean bulkheadFailures = new AtomicBoolean(false);
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    for (int i = 0; i < 20; i++) {
        executorService.submit(() -> {
            try {
                int bulk = bulkhead.bulkhead();
                if (bulk > 5) {
                    success.set(false);
                }
            } catch (BulkheadException be) {
                bulkheadFailures.set(true);
            }
        });
        Thread.sleep(1);//give some chance to the bulkhead to happens
    }
    executorService.shutdown();
    executorService.awaitTermination(5, TimeUnit.SECONDS);
    assertTrue(success.get());
    assertTrue(bulkheadFailures.get());
}
 
Example #11
Source File: ParrallelBulkheadTest.java    From microprofile-fault-tolerance with Apache License 2.0 6 votes vote down vote up
@Override
public Future call() throws Exception {
    log("action " + action);
    log("target " + target);
    Future result = null;

    try {
        result = target.test(action);
    }
    catch( BulkheadException b) {
        log("Might expect a Bulkhead exception from some tests : " + b.toString() + b.getMessage());
    }
    catch( Throwable t ){
        Assert.fail("Unexpected exception: " + t.toString(), t);
    }
    return result;
}
 
Example #12
Source File: ThreadPoolBulkheadTest.java    From smallrye-fault-tolerance with Apache License 2.0 6 votes vote down vote up
@Test
public void shouldRejectMaxPlus1() throws Exception {
    Barrier delayBarrier = Barrier.noninterruptible();
    Barrier startBarrier = Barrier.noninterruptible();

    TestInvocation<Future<String>> invocation = TestInvocation.delayed(startBarrier, delayBarrier,
            () -> completedFuture("shouldRejectMaxPlus1"));
    ThreadPoolBulkhead<String> bulkhead = new ThreadPoolBulkhead<>(invocation, "shouldRejectMaxPlus1", executor, 2, 3,
            null);

    List<TestThread<Future<String>>> threads = new ArrayList<>();

    for (int i = 0; i < 5; i++) {
        threads.add(runOnTestThread(bulkhead));
    }
    waitUntilQueueSize(bulkhead, 3, 500);

    assertThatThrownBy(() -> bulkhead.apply(new InvocationContext<>(null)))
            .isInstanceOf(BulkheadException.class);

    delayBarrier.open();
    for (int i = 0; i < 5; i++) {
        assertThat(threads.get(i).await().get()).isEqualTo("shouldRejectMaxPlus1");
    }
}
 
Example #13
Source File: BulkheadTest.java    From smallrye-fault-tolerance with Apache License 2.0 6 votes vote down vote up
@Test
public void shouldRejectMaxPlus1() throws Exception {
    Barrier startBarrier = Barrier.noninterruptible();
    Barrier delayBarrier = Barrier.noninterruptible();
    CountDownLatch startedLatch = new CountDownLatch(5);
    TestInvocation<String> invocation = TestInvocation.delayed(startBarrier, delayBarrier, startedLatch,
            () -> "shouldRejectMaxPlus1");
    SemaphoreBulkhead<String> bulkhead = new SemaphoreBulkhead<>(invocation, "shouldRejectMaxPlus1", 5, null);

    List<TestThread<String>> threads = new ArrayList<>();

    for (int i = 0; i < 5; i++) {
        threads.add(runOnTestThread(bulkhead));
    }
    startBarrier.await();
    startedLatch.await(); // makes sure that all the threads have put their runnables into bulkhead
    assertThatThrownBy(() -> bulkhead.apply(new InvocationContext<>(() -> "")))
            .isExactlyInstanceOf(BulkheadException.class);
    delayBarrier.open();

    for (int i = 0; i < 5; i++) {
        assertThat(threads.get(i).await()).isEqualTo("shouldRejectMaxPlus1");
    }
}
 
Example #14
Source File: CircuitBreakerClientWithTimeout.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
/**
 * Sleeps for 1000ms, times out after 500ms
 * <p>
 * CircuitBreaker opens after two BulkheadExceptions
 * <p>
 * The method should never throw a BulkheadException so the CircuitBreaker should have no effect
 * 
 * @return should always throw TimeoutException
 */
@CircuitBreaker(successThreshold = 2, requestVolumeThreshold = 2, failureRatio = 0.75, delay = 50000, failOn = BulkheadException.class)
@Timeout(500) // Adjusted by config
public String serviceWithTimeoutWithoutFailOn() {
    try {
        Thread.sleep(TCKConfig.getConfig().getTimeoutInMillis(1000));
        fail("Thread not interrupted by timeout");
    }
    catch (InterruptedException e) {
        // Expected
    }
    return "OK";
}
 
Example #15
Source File: Bulkhead5RapidRetry12MethodSynchBean.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Override
@Bulkhead(value = 5, waitingTaskQueue = 5)
@Retry(retryOn =
 { BulkheadException.class }, delay = 1, delayUnit = ChronoUnit.MICROS,
 maxRetries = 0, maxDuration=999999 )
public Future test(BackendTestDelegate action) throws InterruptedException {
    Utils.log("in business method of bean " + this.getClass().getName());
    return action.perform();
}
 
Example #16
Source File: Bulkhead55RapidRetry10MethodAsynchBean.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Override
@Bulkhead(waitingTaskQueue = 5, value = 5)
@Asynchronous
@Retry(retryOn =
{ BulkheadException.class }, delay = 1, delayUnit = ChronoUnit.MICROS, maxRetries = 10, maxDuration=999999)
public Future test(BackendTestDelegate action) throws InterruptedException {
    Utils.log("in business method of bean " + this.getClass().getName());
    return action.perform();
}
 
Example #17
Source File: Bulkhead5RapidRetry0MethodSynchBean.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Override
@Bulkhead(value = 5)
@Retry(retryOn =
 { BulkheadException.class }, delay = 1, delayUnit = ChronoUnit.MICROS,
 maxRetries = 0, maxDuration=999999 )
public Future test(BackendTestDelegate action) throws InterruptedException {
    Utils.log("in business method of bean " + this.getClass().getName());
    return action.perform();
}
 
Example #18
Source File: Bulkhead55MethodAsynchronousRetryBean.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Override
@Bulkhead(waitingTaskQueue = 5, value = 5)
@Asynchronous
@Retry(retryOn =
{ BulkheadException.class }, delay = 1, delayUnit = ChronoUnit.SECONDS, maxRetries = 10, maxDuration=999999)
public Future test(BackendTestDelegate action) throws InterruptedException {
    Utils.log("in business method of bean " + this.getClass().getName());
    return action.perform();
}
 
Example #19
Source File: RetryTimeoutClient.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
/**
 * Sleeps for 1000ms, times out after 500ms, retries once on BulkheadException
 * <p>
 * Method will never throw a BulkheadException so the Retry annotation should have no effect
 * 
 * @return {@code null}
 */
@Timeout(500)
@Retry(maxRetries = 1, retryOn = BulkheadException.class)
public String serviceWithoutRetryOn() {
    try {
        counterForInvokingServiceWithoutRetryOn++;
        Thread.sleep(config.getTimeoutInMillis(1000));
        fail("Timeout did not interrupt");
    }
    catch (InterruptedException e) {
        // expected
    }
    return null;
}
 
Example #20
Source File: CircuitBreakerBulkheadTest.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
/**
 * A test to ensure that the CircuitBreaker does not open in response to a
 * BulkheadException if {@code failOn} does not include BulkheadException
 * 
 * Uses an asynchronous bulkhead
 * 
 * With requestVolumeThreshold = 3, failureRatio = 1.0,
 * delay = 50000, failOn=TestException the expected behaviour is,
 * 
 * Execution Behaviour
 * ========= =========
 * 1 Fill Bulkhead
 * 2 Fill Bulkhead
 * 3 BulkheadException
 * 4 BulkheadException
 * 5 BulkheadException
 * 6 BulkheadException
 * 7 BulkheadException
 * 
 * @throws InterruptedException if the test is interrupted
 * @throws TimeoutException     if waiting for a result takes too long
 * @throws ExecutionException   if an async method throws an unexpected exception
 */
@Test
public void testCircuitBreaker() throws InterruptedException, ExecutionException, TimeoutException {
    List<AsyncBulkheadTask> tasks = new ArrayList<>();
    try {
        AsyncBulkheadTask task1 = new AsyncBulkheadTask();
        tasks.add(task1);
        Future result1 = asyncBulkheadNoFailClient.test(task1);
        task1.assertStarting(result1);
        
        AsyncBulkheadTask task2 = new AsyncBulkheadTask();
        tasks.add(task2);
        Future result2 = asyncBulkheadNoFailClient.test(task2);
        task2.assertNotStarting();
        
        // While circuit closed, we get a BulkheadException
        // Circuit should not open because failOn does not include BulkheadException
        for (int i = 3; i < 8; i++) {
            AsyncBulkheadTask taski = new AsyncBulkheadTask();
            tasks.add(taski);
            Future resulti = asyncBulkheadNoFailClient.test(taski);
            expect(BulkheadException.class, resulti);
        }
        
        // Tidy Up, complete task1 and 2, check task 2 starts
        task1.complete(CompletableFuture.completedFuture("OK"));
        task2.complete(CompletableFuture.completedFuture("OK"));
        task2.assertStarting(result2);
        
        // Check both tasks return results
        assertEquals(result1.get(2, SECONDS), "OK");
        assertEquals(result2.get(2, SECONDS), "OK");
    }
    finally {
        for (AsyncBulkheadTask task : tasks) {
            task.complete();
        }
    }
}
 
Example #21
Source File: Bulkhead5MethodSynchronousRetry20Bean.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Override
@Bulkhead(value = 5)
@Retry(retryOn =
{ BulkheadException.class }, delay = 1, delayUnit = ChronoUnit.SECONDS, maxRetries = 20, maxDuration=999999)
public Future test(BackendTestDelegate action) throws InterruptedException {
    Utils.log("in business method of bean " + this.getClass().getName());
    return action.perform();
}
 
Example #22
Source File: BulkheadLifecycleTest.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Test
public void noSharingBetweenMethodsOfOneClass() throws InterruptedException, ExecutionException, TimeoutException {
    Barrier barrier = new Barrier();

    MutlipleMethodsBulkheadLifecycleService multipleMethodsService1 = multipleMethodsService.get();
    MutlipleMethodsBulkheadLifecycleService multipleMethodsService2 = multipleMethodsService.get();

    List<Future<Void>> futures = new ArrayList<>();
    try {
        for (int i = 0; i < 4; i++) {
            futures.add(async.run(() -> multipleMethodsService1.service1(barrier)));
            futures.add(async.run(() -> multipleMethodsService1.service2(barrier)));
            futures.add(async.run(() -> multipleMethodsService2.service1(barrier)));
            futures.add(async.run(() -> multipleMethodsService2.service2(barrier)));
        }

        // wait until all submissions have entered the bulkhead
        // - there are 4 iterations of the loop, each invoking 4 methods that will wait on the barrier
        // - there are 2 bulkheads, each allowing 8 executions
        await().atMost(10, TimeUnit.SECONDS).until(() -> barrier.countWaiting() == 16);

        expect(BulkheadException.class, async.run(() -> multipleMethodsService1.service1(barrier)));
        expect(BulkheadException.class, async.run(() -> multipleMethodsService1.service2(barrier)));
        expect(BulkheadException.class, async.run(() -> multipleMethodsService2.service1(barrier)));
        expect(BulkheadException.class, async.run(() -> multipleMethodsService2.service2(barrier)));
    }
    finally {
        try {
            barrier.open();

            for (Future<Void> future : futures) {
                future.get(1, TimeUnit.MINUTES);
            }
        }
        finally {
            multipleMethodsService.destroy(multipleMethodsService1);
            multipleMethodsService.destroy(multipleMethodsService2);
        }
    }
}
 
Example #23
Source File: CompletionStageBulkheadTest.java    From smallrye-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Test
public void shouldRejectMaxPlus1() throws Exception {
    Barrier delayBarrier = Barrier.noninterruptible();

    TestInvocation<CompletionStage<String>> invocation = TestInvocation.delayed(delayBarrier,
            () -> completedFuture("shouldRejectMaxPlus1"));
    CompletionStageBulkhead<String> bulkhead = bulkhead(invocation, "shouldRejectMaxPlus1", 2, 3);

    List<TestThread<CompletionStage<String>>> threads = new ArrayList<>();

    for (int i = 0; i < 5; i++) {
        threads.add(TestThread.runOnTestThread(bulkhead));
    }
    // to make sure all the tasks are in bulkhead:
    waitUntilQueueSize(bulkhead, 3, 1000);

    CompletionStage<String> plus1Call = bulkhead.apply(new InvocationContext<>(null));
    assertThat(plus1Call).isCompletedExceptionally();
    assertThatThrownBy(plus1Call.toCompletableFuture()::get)
            .isInstanceOf(ExecutionException.class)
            .hasCauseInstanceOf(BulkheadException.class);

    delayBarrier.open();
    for (TestThread<CompletionStage<String>> thread : threads) {
        CompletionStage<String> result = thread.await();
        assertThat(result.toCompletableFuture().join()).isEqualTo("shouldRejectMaxPlus1");
    }
}
 
Example #24
Source File: BulkheadConfigTest.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Test
public void testConfigValue() throws Exception {
    // In annotation: value = 5
    // In config:     value = 1
    
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> f1 = executor.submit(() -> {
        bean.serviceValue(waitingFuture);
        return null;
    });
    
    try {
        
        await("Task 1 starting").until(() -> bean.getTasksRunning(), is(1));
        
        Future<?> f2 = executor.submit(() -> {
            bean.serviceValue(waitingFuture);
            return null;
        });
        
        await("Task 2 starting").until(() -> f2.isDone() || bean.getTasksRunning() == 2);
        
        // Now that task 2 is either running or has given us an exception, we can release
        // all waiting tasks and check the result
        waitingFuture.complete(null);
        
        Exceptions.expect(BulkheadException.class, f2);
    }
    finally {
        waitingFuture.complete(null);
        f1.get(1, MINUTES);
    }
}
 
Example #25
Source File: BulkheadConfigTest.java    From microprofile-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Test
public void testWaitingTaskQueue() throws Exception {
    // In annotation: waitingTaskQueue = 5
    //                value = 1
    // In config:     waitingTaskQueue = 1
    
    List<Future<?>> futures = new ArrayList<>();
    
    CompletableFuture<Void> waitingFuture = new CompletableFuture<>();
    Future<?> f1 = bean.serviceWaitingTaskQueue(waitingFuture);
    futures.add(f1);
    try {
        await("Task 1 starting").until(() -> bean.getTasksRunning(), is(1));
        
        Future<?> f2 = bean.serviceWaitingTaskQueue(waitingFuture);
        futures.add(f2);
        
        Future<?> f3 = bean.serviceWaitingTaskQueue(waitingFuture);
        
        // Check f3 is not started or queued
        await().until(() -> f3.isDone());
        Exceptions.expect(BulkheadException.class, f3);
    }
    finally {
        waitingFuture.complete(null);
        for (Future<?> future : futures) {
            future.get(1, MINUTES);
        }
    }
}
 
Example #26
Source File: RetryTestBean.java    From smallrye-fault-tolerance with Apache License 2.0 5 votes vote down vote up
@Retry(retryOn = BulkheadException.class, delay = 500)
@Bulkhead(2)
@Fallback(fallbackMethod = "fallback")
public String callWithRetryOnBulkhead() {
    int attempt = this.attempt.getAndIncrement();
    // both first attempts should take long time
    // without @Asynchronous, the third attempt should fail right away with BulkheadException and should be retried
    // the third attempt should be retried in 500 ms, after the first two calls were processed and should be successful
    // no fallback should be called
    if (attempt < 2) {
        sleep(300L);
    }
    return "call" + attempt;
}
 
Example #27
Source File: TimeoutUninterruptableTest.java    From microprofile-fault-tolerance with Apache License 2.0 4 votes vote down vote up
@Test
public void testTimeoutAsyncBulkhead() throws InterruptedException {
    CompletableFuture<?> waitingFuture = newWaitingFuture();

    long startTime = System.nanoTime();
    Future<Void> resultA = client.serviceTimeoutAsyncBulkhead(waitingFuture);
    expect(TimeoutException.class, resultA);
    long resultTime = System.nanoTime();

    // Should get the TimeoutException after 500ms, allow up to 1500ms
    assertThat("Time for result to be complete", Duration.ofNanos(resultTime - startTime), lessThan(config.getTimeoutInDuration(1500)));

    // Should record one execution
    assertEquals(client.getTimeoutAsyncBulkheadCounter(), 1, "Execution count after first call");

    // At this point, the first execution should still be running, so the next one should get queued
    startTime = System.nanoTime();
    Future<Void> resultB = client.serviceTimeoutAsyncBulkhead(waitingFuture);
    expect(TimeoutException.class, resultB);
    resultTime = System.nanoTime();

    // Should get the TimeoutException after 500ms, allow up to 1500ms
    assertThat("Time for result to be complete", Duration.ofNanos(resultTime - startTime), lessThan(config.getTimeoutInDuration(1500)));

    // This time though, we shouldn't record a second execution since the request timed out before it got to start running
    assertEquals(client.getTimeoutAsyncBulkheadCounter(), 1, "Execution count after second call");

    // Make two more calls with a short gap
    Future<Void> resultC = client.serviceTimeoutAsyncBulkhead(waitingFuture);
    Thread.sleep(config.getTimeoutInMillis(100));
    Future<Void> resultD = client.serviceTimeoutAsyncBulkhead(waitingFuture);

    // The first call should be queued and eventually time out
    // The second call should get a BulkheadException because the queue is full
    expect(TimeoutException.class, resultC);
    expect(BulkheadException.class, resultD);

    // Lastly, neither of these calls actually got to run, so there should be no more executions
    assertEquals(client.getTimeoutAsyncBulkheadCounter(), 1, "Execution count after fourth call");
    
    // Complete the waiting future and check that, after a short wait, we have no additional executions
    waitingFuture.complete(null);
    Thread.sleep(config.getTimeoutInMillis(300));
    assertEquals(client.getTimeoutAsyncBulkheadCounter(), 1, "Execution count after completing all tasks");
}
 
Example #28
Source File: BulkheadLifecycleTest.java    From microprofile-fault-tolerance with Apache License 2.0 4 votes vote down vote up
@Test
public void noSharingBetweenClassesWithCommonSuperclass() throws InterruptedException, ExecutionException, TimeoutException {
    Barrier barrier = new Barrier();

    BulkheadLifecycleServiceSubclass1 service1a = subclassService1.get();
    BulkheadLifecycleServiceSubclass1 service1b = subclassService1.get();

    BulkheadLifecycleServiceSubclass2 service2a = subclassService2.get();
    BulkheadLifecycleServiceSubclass2 service2b = subclassService2.get();

    List<Future<Void>> futures = new ArrayList<>();
    try {
        for (int i = 0; i < 4; i++) {
            futures.add(async.run(() -> service1a.service(barrier)));
            futures.add(async.run(() -> service2a.service(barrier)));
            futures.add(async.run(() -> service1b.service(barrier)));
            futures.add(async.run(() -> service2b.service(barrier)));
        }

        // wait until all submissions have entered the bulkhead
        // - there are 4 iterations of the loop, each invoking 4 methods that will wait on the barrier
        // - there are 2 bulkheads, each allowing 8 executions
        await().atMost(10, TimeUnit.SECONDS).until(() -> barrier.countWaiting() == 16);

        expect(BulkheadException.class, async.run(() -> service1a.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service2a.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service1b.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service2b.service(barrier)));
    }
    finally {
        try {
            barrier.open();

            for (Future<Void> future : futures) {
                future.get(1, TimeUnit.MINUTES);
            }
        }
        finally {
            subclassService1.destroy(service1a);
            subclassService1.destroy(service1b);
            subclassService2.destroy(service2a);
            subclassService2.destroy(service2b);
        }
    }
}
 
Example #29
Source File: BulkheadLifecycleTest.java    From microprofile-fault-tolerance with Apache License 2.0 4 votes vote down vote up
@Test
public void noSharingBetweenClasses() throws InterruptedException, ExecutionException, TimeoutException {
    Barrier barrier = new Barrier();

    BulkheadLifecycleService1 service1a = service1.get();
    BulkheadLifecycleService1 service1b = service1.get();

    BulkheadLifecycleService2 service2a = service2.get();
    BulkheadLifecycleService2 service2b = service2.get();

    List<Future<Void>> futures = new ArrayList<>();
    try {
        for (int i = 0; i < 4; i++) {
            futures.add(async.run(() -> service1a.service(barrier)));
            futures.add(async.run(() -> service2a.service(barrier)));
            futures.add(async.run(() -> service1b.service(barrier)));
            futures.add(async.run(() -> service2b.service(barrier)));
        }

        // wait until all submissions have entered the bulkhead
        // - there are 4 iterations of the loop, each invoking 4 methods that will wait on the barrier
        // - there are 2 bulkheads, each allowing 8 executions
        await().atMost(10, TimeUnit.SECONDS).until(() -> barrier.countWaiting() == 16);

        expect(BulkheadException.class, async.run(() -> service1a.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service2a.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service1b.service(barrier)));
        expect(BulkheadException.class, async.run(() -> service2b.service(barrier)));
    }
    finally {
        try {
            barrier.open();

            for (Future<Void> future : futures) {
                future.get(1, TimeUnit.MINUTES);
            }
        }
        finally {
            service1.destroy(service1a);
            service1.destroy(service1b);
            service2.destroy(service2a);
            service2.destroy(service2b);
        }
    }
}
 
Example #30
Source File: ThreadPoolBulkheadTest.java    From smallrye-fault-tolerance with Apache License 2.0 4 votes vote down vote up
@Test
public void shouldLetMaxPlus1After1Canceled() throws Exception {
    Barrier delayBarrier = Barrier.interruptible();
    CountDownLatch invocationsStarted = new CountDownLatch(2);

    TestInvocation<Future<String>> invocation = TestInvocation.immediatelyReturning(() -> {
        invocationsStarted.countDown();
        delayBarrier.await();
        return completedFuture("shouldLetMaxPlus1After1Canceled");
    });

    ThreadPoolBulkhead<String> bulkhead = new ThreadPoolBulkhead<>(invocation, "shouldLetMaxPlus1After1Canceled", executor,
            2, 3, null);

    List<TestThread<Future<String>>> threads = new ArrayList<>();

    for (int i = 0; i < 4; i++) {
        threads.add(runOnTestThread(bulkhead));
    }
    // to make sure the fifth added is enqueued, wait until two are started
    invocationsStarted.await();

    threads.add(runOnTestThread(bulkhead));

    waitUntilQueueSize(bulkhead, 3, 1000);

    TestThread<Future<String>> failedThread = runOnTestThread(bulkhead);
    assertThatThrownBy(failedThread::await).isInstanceOf(BulkheadException.class);

    threads.remove(4).interrupt(); // cancel and remove from the list
    waitUntilQueueSize(bulkhead, 2, 1000);

    threads.add(runOnTestThread(bulkhead));
    waitUntilQueueSize(bulkhead, 3, 1000);

    delayBarrier.open();

    for (TestThread<Future<String>> thread : threads) {
        assertThat(thread.await().get()).isEqualTo("shouldLetMaxPlus1After1Canceled");
    }
}