public void run() throws Throwable { runnable.run(); } }
/** * Creates a runnable which is restricted by a RateLimiter. * * @param rateLimiter the RateLimiter * @param runnable the original runnable * @return a runnable which is restricted by a RateLimiter. */ static CheckedRunnable decorateCheckedRunnable(RateLimiter rateLimiter, CheckedRunnable runnable) { return () -> { waitForPermission(rateLimiter); runnable.run(); }; }
/** * Starts an asynchronous computation, backed by the given {@link Executor}. * * @param executor An {@link Executor}. * @param unit A unit of work. * @return A new Future instance which results in nothing. * @throws NullPointerException if one of executor or unit is null. */ static Future<Void> run(Executor executor, CheckedRunnable unit) { Objects.requireNonNull(executor, "executor is null"); Objects.requireNonNull(unit, "unit is null"); return of(executor, () -> { unit.run(); return null; }); }
/** * Provides try's finally behavior no matter what the result of the operation is. * * @param runnable A runnable * @return this {@code Try}. * @throws NullPointerException if {@code runnable} is null */ default Try<T> andFinallyTry(CheckedRunnable runnable) { Objects.requireNonNull(runnable, "runnable is null"); try { runnable.run(); return this; } catch (Throwable t) { return new Failure<>(t); } }
/** * Returns an unchecked {@link Runnable} that will <em>sneaky throw</em> if an exceptions occurs when running the unit of work. * * @return a new {@link Runnable} that throws a {@code Throwable}. */ default Runnable unchecked() { return () -> { try { run(); } catch(Throwable x) { sneakyThrow(x); } }; } }
/** * Creates a Try of a CheckedRunnable. * * @param runnable A checked runnable * @return {@code Success(null)} if no exception occurs, otherwise {@code Failure(throwable)} if an exception occurs * calling {@code runnable.run()}. */ static Try<Void> run(CheckedRunnable runnable) { Objects.requireNonNull(runnable, "runnable is null"); try { runnable.run(); return new Success<>(null); // null represents the absence of an value, i.e. Void } catch (Throwable t) { return new Failure<>(t); } }
/** * Returns a runnable which is decorated by a bulkhead. * * @param bulkhead the bulkhead * @param runnable the original runnable * * @return a runnable which is decorated by a Bulkhead. */ static CheckedRunnable decorateCheckedRunnable(Bulkhead bulkhead, CheckedRunnable runnable){ return () -> { BulkheadUtils.isCallPermitted(bulkhead); try{ runnable.run(); } finally { bulkhead.onComplete(); } }; }
/** * Returns a runnable which is decorated by a CircuitBreaker. * * @param circuitBreaker the CircuitBreaker * @param runnable the original runnable * * @return a runnable which is decorated by a CircuitBreaker. */ static CheckedRunnable decorateCheckedRunnable(CircuitBreaker circuitBreaker, CheckedRunnable runnable){ return () -> { CircuitBreakerUtils.isCallPermitted(circuitBreaker); long start = System.nanoTime(); try{ runnable.run(); long durationInNanos = System.nanoTime() - start; circuitBreaker.onSuccess(durationInNanos); } catch (Throwable throwable){ long durationInNanos = System.nanoTime() - start; circuitBreaker.onError(durationInNanos, throwable); throw throwable; } }; }
} else { try { runnable.run(); return this; } catch (Throwable t) {
/** * Creates a timed runnable. * @param timer the timer to use * @param runnable the original runnable * @return a timed runnable */ static CheckedRunnable decorateCheckedRunnable(Timer timer, CheckedRunnable runnable){ return () -> { final Timer.Context context = timer.context(); try { runnable.run(); context.onSuccess(); }catch (Throwable e){ context.onError(); throw e; } }; }
/** * Creates a timed runnable. * * @param meter the call meter to use * @param runnable the original runnable * @return a timed runnable */ static CheckedRunnable decorateCheckedRunnable(CallMeterBase meter, CheckedRunnable runnable){ return () -> { final Timer timer = meter.startTimer(); try { runnable.run(); timer.onSuccess(); }catch (Throwable e){ timer.onError(); throw e; } }; }
/** * Creates a retryable runnable. * * @param retry the retry context * @param runnable the original runnable * * @return a retryable runnable */ static CheckedRunnable decorateCheckedRunnable(Retry retry, CheckedRunnable runnable){ return () -> { Retry.Context context = retry.context(); do try { runnable.run(); context.onSuccess(); break; } catch (Exception exception) { context.onError(exception); } while (true); }; }
@Test public void decorateCheckedRunnable() throws Throwable { CheckedRunnable runnable = mock(CheckedRunnable.class); CheckedRunnable decorated = RateLimiter.decorateCheckedRunnable(limit, runnable); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(false); Try decoratedRunnableResult = Try.run(decorated); then(decoratedRunnableResult.isFailure()).isTrue(); then(decoratedRunnableResult.getCause()).isInstanceOf(RequestNotPermitted.class); verify(runnable, never()).run(); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(true); Try secondRunnableResult = Try.run(decorated); then(secondRunnableResult.isSuccess()).isTrue(); verify(runnable, times(1)).run(); }
@Test public void shouldDecorateCheckedRunnableAndReturnWithSuccess() throws Throwable { // And measure the call with a Timer CheckedRunnable timedRunnable = Timer.decorateCheckedRunnable(timer, helloWorldService::sayHelloWorldWithException); timedRunnable.run(); assertThat(timer.getMetrics().getNumberOfTotalCalls()).isEqualTo(1); assertThat(timer.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); assertThat(timer.getMetrics().getNumberOfFailedCalls()).isEqualTo(0); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).sayHelloWorldWithException(); }
@Test public void shouldDecorateCheckedRunnableAndReturnWithSuccess() throws Throwable { // Given CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults(); CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("testName"); CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics(); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(0); //When CheckedRunnable checkedRunnable = CircuitBreaker.decorateCheckedRunnable(circuitBreaker, helloWorldService::sayHelloWorldWithException); //Then checkedRunnable.run(); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(1); assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(0); assertThat(metrics.getNumberOfSuccessfulCalls()).isEqualTo(1); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).sayHelloWorldWithException(); }
@Test public void shouldDecorateCheckedRunnableAndReturnWithSuccess() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When Bulkhead.decorateCheckedRunnable(bulkhead, helloWorldService::sayHelloWorldWithException) .run(); // Then assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).sayHelloWorldWithException(); }
/** * Creates a runnable which is restricted by a RateLimiter. * * @param rateLimiter the RateLimiter * @param runnable the original runnable * @return a runnable which is restricted by a RateLimiter. */ static CheckedRunnable decorateCheckedRunnable(RateLimiter rateLimiter, CheckedRunnable runnable) { return () -> { waitForPermission(rateLimiter); runnable.run(); }; }
/** * Starts an asynchronous computation, backed by the given {@link Executor}. * * @param executor An {@link Executor}. * @param unit A unit of work. * @return A new Future instance which results in nothing. * @throws NullPointerException if one of executor or unit is null. */ static Future<Void> run(Executor executor, CheckedRunnable unit) { Objects.requireNonNull(executor, "executor is null"); Objects.requireNonNull(unit, "unit is null"); return of(executor, () -> { unit.run(); return null; }); }
/** * Returns an unchecked {@link Runnable} that will <em>sneaky throw</em> if an exceptions occurs when running the unit of work. * * @return a new {@link Runnable} that throws a {@code Throwable}. */ default Runnable unchecked() { return () -> { try { run(); } catch(Throwable x) { sneakyThrow(x); } }; } }
/** * Provides try's finally behavior no matter what the result of the operation is. * * @param runnable A runnable * @return this {@code Try}. * @throws NullPointerException if {@code runnable} is null */ default Try<T> andFinallyTry(CheckedRunnable runnable) { Objects.requireNonNull(runnable, "runnable is null"); try { runnable.run(); return this; } catch (Throwable t) { return new Failure<>(t); } }