CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-micronaut

Modern, JVM-based framework for building modular, easily testable microservice and serverless applications with compile-time DI and fast startup.

Pending
Overview
Eval results
Files

retry.mddocs/

Retry and Circuit Breaker

Micronaut provides comprehensive resilience patterns including retry logic, circuit breakers, and bulkhead isolation to handle failures and improve application reliability.

Capabilities

Retry Logic

Automatically retry failed operations with configurable strategies.

/**
 * Retry configuration and usage
 */
@Singleton
public class ExternalService {
    
    @Retryable(attempts = "3", delay = "1s")
    public String callExternal() {
        // Method will be retried up to 3 times with 1 second delay
        return restClient.getData();
    }
    
    @Retryable(attempts = "5", delay = "2s", multiplier = "2")
    public String callWithBackoff() {
        // Exponential backoff: 2s, 4s, 8s, 16s
        return restClient.getData();
    }
    
    @Retryable(
        attempts = "3",
        includes = {ConnectException.class, SocketTimeoutException.class},
        excludes = {IllegalArgumentException.class}
    )
    public String callWithSpecificExceptions() {
        // Only retry on specific exceptions
        return restClient.getData();
    }
    
    @Retryable(attempts = "3", delay = "1s")
    Single<String> reactiveRetry() {
        // Reactive retry support
        return Single.fromCallable(() -> restClient.getData());
    }
}

Circuit Breaker

Protect against cascading failures with circuit breaker patterns.

/**
 * Circuit breaker configuration
 */
@Singleton
public class ReliableService {
    
    @CircuitBreaker
    public String reliableCall() {
        // Default circuit breaker configuration
        return externalService.call();
    }
    
    @CircuitBreaker(
        attempts = "5",
        openTimeout = "30s", 
        resetTimeout = "60s"
    )
    public String configuredCircuitBreaker() {
        // Custom circuit breaker settings
        return externalService.call();
    }
    
    @CircuitBreaker(includes = {ConnectException.class})
    @Fallback
    public String circuitBreakerWithFallback() {
        // Circuit breaker with fallback method
        return externalService.call();
    }
    
    // Fallback method for circuitBreakerWithFallback
    public String circuitBreakerWithFallback(CircuitOpenException ex) {
        return "Service temporarily unavailable";
    }
}

Bulkhead Pattern

Isolate different parts of the application to prevent resource exhaustion.

/**
 * Bulkhead isolation
 */
@Singleton
public class IsolatedService {
    
    @Bulkhead(value = "critical-operations", maxConcurrency = 10)
    public String criticalOperation() {
        // Limited to 10 concurrent executions
        return performCriticalWork();
    }
    
    @Bulkhead(value = "background-tasks", maxConcurrency = 5, maxWaitDuration = "5s")
    public CompletableFuture<String> backgroundTask() {
        // Background tasks with wait timeout
        return CompletableFuture.supplyAsync(this::performBackgroundWork);
    }
}

Timeout Protection

Add timeout protection to prevent operations from hanging indefinitely.

/**
 * Timeout configuration
 */
@Singleton
public class TimedService {
    
    @TimedOut("5s")
    public String timedOperation() {
        // Operation will timeout after 5 seconds
        return longRunningOperation();
    }
    
    @TimedOut("10s")
    @Fallback
    public String timedOperationWithFallback() {
        // Timeout with fallback
        return longRunningOperation();
    }
    
    // Fallback method for timeout
    public String timedOperationWithFallback(TimeoutException ex) {
        return "Operation timed out, using cached result";
    }
    
    @TimedOut("3s")
    Single<String> reactiveTimeout() {
        // Reactive timeout support
        return Single.fromCallable(this::longRunningOperation);
    }
}

Combined Resilience Patterns

Combine multiple resilience patterns for comprehensive protection.

/**
 * Combined resilience patterns
 */
@Singleton
public class ResilientService {
    
    @Retryable(attempts = "3", delay = "1s")
    @CircuitBreaker(attempts = "5", openTimeout = "30s")
    @TimedOut("10s")
    @Fallback
    public String resilientOperation() {
        // Combined retry, circuit breaker, timeout, and fallback
        return externalService.call();
    }
    
    // Fallback for resilientOperation
    public String resilientOperation(Exception ex) {
        if (ex instanceof CircuitOpenException) {
            return "Circuit breaker is open";
        } else if (ex instanceof TimeoutException) {
            return "Operation timed out";
        } else {
            return "Operation failed after retries";
        }
    }
    
    @Bulkhead("api-calls")
    @Retryable(attempts = "2")
    @CircuitBreaker
    Publisher<String> resilientReactiveOperation() {
        // Reactive resilience patterns
        return Flowable.fromCallable(() -> externalService.call());
    }
}

Configuration

Configure resilience patterns through application properties.

/**
 * Resilience configuration properties
 */
@ConfigurationProperties("resilience")
public class ResilienceConfiguration {
    
    @ConfigurationProperties("retry")
    public static class RetryConfiguration {
        private int attempts = 3;
        private Duration delay = Duration.ofSeconds(1);
        private double multiplier = 1.0;
        
        // getters and setters
    }
    
    @ConfigurationProperties("circuit-breaker")
    public static class CircuitBreakerConfiguration {
        private int attempts = 5;
        private Duration openTimeout = Duration.ofSeconds(30);
        private Duration resetTimeout = Duration.ofMinutes(1);
        
        // getters and setters
    }
    
    @ConfigurationProperties("bulkhead")
    public static class BulkheadConfiguration {
        private int maxConcurrency = 10;
        private Duration maxWaitDuration = Duration.ofSeconds(5);
        
        // getters and setters
    }
}

Types

// Resilience annotations
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryable {
    String attempts() default "3";
    String delay() default "1s";
    String multiplier() default "1.0";
    Class<? extends Throwable>[] includes() default {};
    Class<? extends Throwable>[] excludes() default {};
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CircuitBreaker {
    String attempts() default "20";
    String openTimeout() default "20s";
    String resetTimeout() default "20s";
    Class<? extends Throwable>[] includes() default {};
    Class<? extends Throwable>[] excludes() default {};
    double failureThreshold() default 0.5;
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bulkhead {
    String value() default "";
    int maxConcurrency() default 10;
    String maxWaitDuration() default "0s";
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TimedOut {
    String value();
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Fallback {
}

// Exception types
public class CircuitOpenException extends RuntimeException {
    public CircuitOpenException(String message);
    public CircuitOpenException(String message, Throwable cause);
}

public class BulkheadRejectionException extends RuntimeException {
    public BulkheadRejectionException(String message);
    public BulkheadRejectionException(String message, Throwable cause);
}

// Circuit breaker states
public enum CircuitState {
    CLOSED, OPEN, HALF_OPEN
}

// Retry context
public interface RetryContext {
    int getCurrentAttempt();
    int getMaxAttempts();
    Duration getDelay();
    Throwable getLastException();
}

Install with Tessl CLI

npx tessl i tessl/maven-micronaut

docs

aop.md

configuration.md

dependency-injection.md

functions.md

http-client.md

http-server.md

index.md

management.md

messaging.md

reactive.md

retry.md

scheduling.md

websocket.md

tile.json