use of io.micronaut.core.convert.value.MutableConvertibleValues in project micronaut-core by micronaut-projects.
the class DefaultRetryInterceptor method intercept.
@Nullable
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
Optional<AnnotationValue<Retryable>> opt = context.findAnnotation(Retryable.class);
if (!opt.isPresent()) {
return context.proceed();
}
AnnotationValue<Retryable> retry = opt.get();
boolean isCircuitBreaker = context.hasStereotype(CircuitBreaker.class);
MutableRetryState retryState;
AnnotationRetryStateBuilder retryStateBuilder = new AnnotationRetryStateBuilder(context);
if (isCircuitBreaker) {
long timeout = context.getValue(CircuitBreaker.class, "reset", Duration.class).map(Duration::toMillis).orElse(Duration.ofSeconds(DEFAULT_CIRCUIT_BREAKER_TIMEOUT_IN_MILLIS).toMillis());
retryState = circuitContexts.computeIfAbsent(context.getExecutableMethod(), method -> new CircuitBreakerRetry(timeout, retryStateBuilder, context, eventPublisher));
} else {
retryState = (MutableRetryState) retryStateBuilder.build();
}
MutableConvertibleValues<Object> attrs = context.getAttributes();
attrs.put(RetryState.class.getName(), retry);
InterceptedMethod interceptedMethod = InterceptedMethod.of(context);
try {
retryState.open();
// Retry method call before we have actual Publisher/CompletionStage result
Object result = retrySync(context, retryState, interceptedMethod);
switch(interceptedMethod.resultType()) {
case PUBLISHER:
Flux<Object> reactiveSequence = Flux.from((Publisher<?>) result);
return interceptedMethod.handleResult(reactiveSequence.onErrorResume(retryFlowable(context, retryState, reactiveSequence)).doOnNext(o -> retryState.close(null)));
case COMPLETION_STAGE:
CompletableFuture<Object> newFuture = new CompletableFuture<>();
Supplier<CompletionStage<?>> retrySupplier = () -> interceptedMethod.interceptResultAsCompletionStage(this);
((CompletionStage<?>) result).whenComplete(retryCompletable(context, retryState, newFuture, retrySupplier));
return interceptedMethod.handleResult(newFuture);
case SYNCHRONOUS:
retryState.close(null);
return result;
default:
return interceptedMethod.unsupported();
}
} catch (Exception e) {
return interceptedMethod.handleException(e);
}
}
Aggregations