Search in sources :

Example 1 with CircuitBreakerOperator

use of io.github.resilience4j.circuitbreaker.operator.CircuitBreakerOperator in project resilience4j by resilience4j.

the class CircuitBreakerMethodInterceptor method invoke.

@SuppressWarnings("unchecked")
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
    CircuitBreaker annotation = invocation.getMethod().getAnnotation(CircuitBreaker.class);
    RecoveryFunction<?> recoveryFunction = annotation.recovery().newInstance();
    if (registry == null) {
        registry = CircuitBreakerRegistry.ofDefaults();
    }
    io.github.resilience4j.circuitbreaker.CircuitBreaker breaker = registry.circuitBreaker(annotation.name());
    if (breaker == null) {
        return invocation.proceed();
    }
    Class<?> returnType = invocation.getMethod().getReturnType();
    if (Promise.class.isAssignableFrom(returnType)) {
        Promise<?> result = (Promise<?>) proceed(invocation, breaker, recoveryFunction);
        if (result != null) {
            CircuitBreakerTransformer transformer = CircuitBreakerTransformer.of(breaker).recover(recoveryFunction);
            result = result.transform(transformer);
        }
        return result;
    } else if (Observable.class.isAssignableFrom(returnType)) {
        Observable<?> result = (Observable<?>) proceed(invocation, breaker, recoveryFunction);
        if (result != null) {
            CircuitBreakerOperator operator = CircuitBreakerOperator.of(breaker);
            result = result.lift(operator).onErrorReturn(t -> recoveryFunction.apply((Throwable) t));
        }
        return result;
    } else if (Flowable.class.isAssignableFrom(returnType)) {
        Flowable<?> result = (Flowable<?>) proceed(invocation, breaker, recoveryFunction);
        if (result != null) {
            CircuitBreakerOperator operator = CircuitBreakerOperator.of(breaker);
            result = result.lift(operator).onErrorReturn(t -> recoveryFunction.apply((Throwable) t));
        }
        return result;
    } else if (Single.class.isAssignableFrom(returnType)) {
        Single<?> result = (Single<?>) proceed(invocation, breaker, recoveryFunction);
        if (result != null) {
            CircuitBreakerOperator operator = CircuitBreakerOperator.of(breaker);
            result = result.lift(operator).onErrorReturn(t -> recoveryFunction.apply((Throwable) t));
        }
        return result;
    } else if (CompletionStage.class.isAssignableFrom(returnType)) {
        final CompletableFuture promise = new CompletableFuture<>();
        if (breaker.isCallPermitted()) {
            CompletionStage<?> result = (CompletionStage<?>) proceed(invocation, breaker, recoveryFunction);
            if (result != null) {
                long start = System.nanoTime();
                result.whenComplete((v, t) -> {
                    long durationInNanos = System.nanoTime() - start;
                    if (t != null) {
                        breaker.onError(durationInNanos, t);
                        try {
                            promise.complete(recoveryFunction.apply((Throwable) t));
                        } catch (Exception e) {
                            promise.completeExceptionally(e);
                        }
                    } else {
                        breaker.onSuccess(durationInNanos);
                        promise.complete(v);
                    }
                });
            }
        } else {
            Throwable t = new CircuitBreakerOpenException(String.format("CircuitBreaker '%s' is open", breaker.getName()));
            try {
                promise.complete(recoveryFunction.apply((Throwable) t));
            } catch (Throwable t2) {
                promise.completeExceptionally(t2);
            }
        }
        return promise;
    }
    return proceed(invocation, breaker, recoveryFunction);
}
Also used : CircuitBreakerOperator(io.github.resilience4j.circuitbreaker.operator.CircuitBreakerOperator) Inject(com.google.inject.Inject) Promise(ratpack.exec.Promise) CompletableFuture(java.util.concurrent.CompletableFuture) CircuitBreakerOperator(io.github.resilience4j.circuitbreaker.operator.CircuitBreakerOperator) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) CircuitBreakerRegistry(io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry) Single(io.reactivex.Single) RecoveryFunction(io.github.resilience4j.ratpack.recovery.RecoveryFunction) MethodInterceptor(org.aopalliance.intercept.MethodInterceptor) MethodInvocation(org.aopalliance.intercept.MethodInvocation) CompletionStage(java.util.concurrent.CompletionStage) Flowable(io.reactivex.Flowable) Observable(io.reactivex.Observable) Observable(io.reactivex.Observable) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) Promise(ratpack.exec.Promise) CompletableFuture(java.util.concurrent.CompletableFuture) Single(io.reactivex.Single) CompletionStage(java.util.concurrent.CompletionStage) Flowable(io.reactivex.Flowable)

Aggregations

Inject (com.google.inject.Inject)1 CircuitBreakerOpenException (io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException)1 CircuitBreakerRegistry (io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry)1 CircuitBreakerOperator (io.github.resilience4j.circuitbreaker.operator.CircuitBreakerOperator)1 RecoveryFunction (io.github.resilience4j.ratpack.recovery.RecoveryFunction)1 Flowable (io.reactivex.Flowable)1 Observable (io.reactivex.Observable)1 Single (io.reactivex.Single)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CompletionStage (java.util.concurrent.CompletionStage)1 MethodInterceptor (org.aopalliance.intercept.MethodInterceptor)1 MethodInvocation (org.aopalliance.intercept.MethodInvocation)1 Promise (ratpack.exec.Promise)1