Search in sources :

Example 1 with Retryable

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);
}
Also used : Retryable(io.micronaut.retry.annotation.Retryable) Duration(java.time.Duration) DefaultRetryPredicate(io.micronaut.retry.annotation.DefaultRetryPredicate) RetryPredicate(io.micronaut.retry.annotation.RetryPredicate)

Example 2 with Retryable

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);
    }
}
Also used : RetryState(io.micronaut.retry.RetryState) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) InterceptedMethod(io.micronaut.aop.InterceptedMethod) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ExecutableMethod(io.micronaut.inject.ExecutableMethod) TaskExecutors(io.micronaut.scheduling.TaskExecutors) MethodInterceptor(io.micronaut.aop.MethodInterceptor) Nullable(io.micronaut.core.annotation.Nullable) Duration(java.time.Duration) Map(java.util.Map) Retryable(io.micronaut.retry.annotation.Retryable) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) MutableConvertibleValues(io.micronaut.core.convert.value.MutableConvertibleValues) ExecutorService(java.util.concurrent.ExecutorService) RetryEvent(io.micronaut.retry.event.RetryEvent) Logger(org.slf4j.Logger) Publisher(org.reactivestreams.Publisher) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ApplicationEventPublisher(io.micronaut.context.event.ApplicationEventPublisher) Singleton(jakarta.inject.Singleton) CircuitBreaker(io.micronaut.retry.annotation.CircuitBreaker) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) ChronoUnit(java.time.temporal.ChronoUnit) CompletionStage(java.util.concurrent.CompletionStage) MethodInvocationContext(io.micronaut.aop.MethodInvocationContext) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Optional(java.util.Optional) InterceptPhase(io.micronaut.aop.InterceptPhase) Named(jakarta.inject.Named) InterceptedMethod(io.micronaut.aop.InterceptedMethod) CompletableFuture(java.util.concurrent.CompletableFuture) Retryable(io.micronaut.retry.annotation.Retryable) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) CompletionStage(java.util.concurrent.CompletionStage) RetryState(io.micronaut.retry.RetryState) Nullable(io.micronaut.core.annotation.Nullable)

Example 3 with Retryable

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);
    }
}
Also used : ConfigurationException(io.micronaut.context.exceptions.ConfigurationException) AuthToken(org.neo4j.driver.AuthToken) URI(java.net.URI) Retryable(io.micronaut.retry.annotation.Retryable)

Aggregations

Retryable (io.micronaut.retry.annotation.Retryable)3 Duration (java.time.Duration)2 InterceptPhase (io.micronaut.aop.InterceptPhase)1 InterceptedMethod (io.micronaut.aop.InterceptedMethod)1 MethodInterceptor (io.micronaut.aop.MethodInterceptor)1 MethodInvocationContext (io.micronaut.aop.MethodInvocationContext)1 ApplicationEventPublisher (io.micronaut.context.event.ApplicationEventPublisher)1 ConfigurationException (io.micronaut.context.exceptions.ConfigurationException)1 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)1 Nullable (io.micronaut.core.annotation.Nullable)1 MutableConvertibleValues (io.micronaut.core.convert.value.MutableConvertibleValues)1 ExecutableMethod (io.micronaut.inject.ExecutableMethod)1 RetryState (io.micronaut.retry.RetryState)1 CircuitBreaker (io.micronaut.retry.annotation.CircuitBreaker)1 DefaultRetryPredicate (io.micronaut.retry.annotation.DefaultRetryPredicate)1 RetryPredicate (io.micronaut.retry.annotation.RetryPredicate)1 RetryEvent (io.micronaut.retry.event.RetryEvent)1 TaskExecutors (io.micronaut.scheduling.TaskExecutors)1 Named (jakarta.inject.Named)1 Singleton (jakarta.inject.Singleton)1