@Override protected boolean isCallPermitted() { return bulkhead.isCallPermitted(); }
private boolean acquireCallPermit() { boolean callPermitted = false; if (permitted.compareAndSet(Permit.PENDING, Permit.ACQUIRED)) { callPermitted = bulkhead.isCallPermitted(); if (!callPermitted) { permitted.set(Permit.REJECTED); } } return callPermitted; }
private boolean acquireCallPermit() { boolean callPermitted = false; if (permitted.compareAndSet(Permit.PENDING, Permit.ACQUIRED)) { callPermitted = bulkhead.isCallPermitted(); if (!callPermitted) { permitted.set(Permit.REJECTED); } } return callPermitted; }
public static void isCallPermitted(Bulkhead bulkhead) { if(!bulkhead.isCallPermitted()) { throw new BulkheadFullException(String.format("Bulkhead '%s' is full", bulkhead.getName())); } } }
@Test public void testBulkhead() throws InterruptedException { bulkhead.isCallPermitted(); bulkhead.isCallPermitted(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); bulkhead.isCallPermitted(); bulkhead.onComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); bulkhead.onComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(2); bulkhead.isCallPermitted(); testSubscriber.assertValueCount(6) .assertValues(CALL_PERMITTED, CALL_PERMITTED, CALL_REJECTED, CALL_FINISHED, CALL_FINISHED, CALL_PERMITTED); }
@Test public void shouldNotReleaseBulkheadWhenWasDisposedAfterNotPermittedSubscribe() throws Exception { // Given Disposable disposable = mock(Disposable.class); MaybeObserver childObserver = mock(MaybeObserver.class); MaybeObserver decoratedObserver = BulkheadOperator.of(bulkhead).apply(childObserver); bulkhead.isCallPermitted(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); decoratedObserver.onSubscribe(disposable); // When ((Disposable) decoratedObserver).dispose(); // Then assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldNotReleaseBulkheadWhenWasDisposedAfterNotPermittedSubscribe() throws Exception { // Given Disposable disposable = mock(Disposable.class); SingleObserver childObserver = mock(SingleObserver.class); SingleObserver decoratedObserver = BulkheadOperator.of(bulkhead).apply(childObserver); bulkhead.isCallPermitted(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); decoratedObserver.onSubscribe(disposable); // When ((Disposable) decoratedObserver).dispose(); // Then assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.just("Event") .transform(BulkheadOperator.of(bulkhead))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorNotOnSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.error(new IOException("BAM!")).delayElement(Duration.ofMillis(1)) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); } }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorDuringSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Flux.error(new IOException("BAM!")) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorNotOnSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Flux.error(new IOException("BAM!"), true) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); } }
@Test public void shouldEmitBulkheadFullExceptionEvenWhenErrorDuringSubscribe() { bulkhead.isCallPermitted(); StepVerifier.create( Mono.error(new IOException("BAM!")) .transform(BulkheadOperator.of(bulkhead, Schedulers.immediate()))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldReturnFailureWithRuntimeException() { // Given BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(2).build(); Bulkhead bulkhead = Bulkhead.of("test", config); bulkhead.isCallPermitted(); //v When CheckedRunnable checkedRunnable = Bulkhead.decorateCheckedRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try result = Try.run(checkedRunnable); //Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); StepVerifier.create( Flux.just("Event") .transform(BulkheadOperator.of(bulkhead))) .expectSubscription() .expectError(BulkheadFullException.class) .verify(Duration.ofSeconds(1)); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldConsumeOnCallRejectedEvent() { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When bulkhead.getEventPublisher() .onCallRejected(event -> logger.info(event.getEventType().toString())); bulkhead.isCallPermitted(); Try.ofSupplier(Bulkhead.decorateSupplier(bulkhead,helloWorldService::returnHelloWorld)); // Then then(logger).should(times(1)).info("CALL_REJECTED"); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Completable.complete() .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Flowable.fromArray("Event 1", "Event 2") .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Maybe.just(1) .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Observable.fromArray("Event 1", "Event 2") .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }
@Test public void shouldEmitErrorWithBulkheadFullException() { bulkhead.isCallPermitted(); Single.just(1) .lift(BulkheadOperator.of(bulkhead)) .test() .assertSubscribed() .assertError(BulkheadFullException.class) .assertNotComplete(); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(0); }