use of io.micronaut.retry.annotation.Retryable in project micronaut-core by micronaut-projects.
the class AnnotationRetryStateBuilder method build.
@Override
public RetryState build() {
AnnotationValue<Retryable> retry = annotationMetadata.findAnnotation(Retryable.class).orElseThrow(() -> new IllegalStateException("Missing @Retryable annotation"));
int attempts = retry.get(ATTEMPTS, Integer.class).orElse(DEFAULT_RETRY_ATTEMPTS);
Duration delay = retry.get(DELAY, Duration.class).orElse(Duration.ofSeconds(1));
Class<? extends RetryPredicate> predicateClass = retry.get(PREDICATE, Class.class).orElse(DefaultRetryPredicate.class);
RetryPredicate predicate = createPredicate(predicateClass, retry);
Class<? extends Throwable> capturedException = retry.get(CAPTUREDEXCEPTION, Class.class).orElse(RuntimeException.class);
return new SimpleRetry(attempts, retry.get(MULTIPLIER, Double.class).orElse(0d), delay, retry.get(MAX_DELAY, Duration.class).orElse(null), predicate, capturedException);
}
use of io.micronaut.retry.annotation.Retryable 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);
}
}
use of io.micronaut.retry.annotation.Retryable in project micronaut-neo4j by micronaut-projects.
the class Neo4jDriverBuilder method buildDriver.
/**
* Builds the Neo4j driver and retries the connection if there is a {@link ServiceUnavailableException} exception.
* @return The Neo4j driver
*/
@Retryable(ServiceUnavailableException.class)
public Driver buildDriver() {
Neo4jBoltConfiguration configuration = this.boltConfiguration;
List<URI> uris = configuration.getUris();
Optional<AuthToken> configuredAuthToken = configuration.getAuthToken();
AuthToken authToken = configuredAuthToken.orElse(null);
if (uris.size() == 1) {
URI uri = uris.get(0);
String userInfo = uri.getUserInfo();
if (authToken == null && StringUtils.hasText(userInfo)) {
String[] info = userInfo.split(":");
if (info.length == 2) {
authToken = AuthTokens.basic(info[0], info[1]);
}
}
return GraphDatabase.driver(uri, authToken, configuration.getConfig());
} else if (!uris.isEmpty()) {
return GraphDatabase.routingDriver(uris, authToken, configuration.getConfig());
} else {
throw new ConfigurationException("At least one Neo4j URI should be specified eg. neo4j.uri=" + Neo4jBoltConfiguration.DEFAULT_URI);
}
}
Aggregations