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);
}
Aggregations