Resilience
resilience2RetryWithBackoff
- Path
- pkg18resiliencepatterns/resilience2RetryWithBackoff.java
- Package
- pkg18resiliencepatterns
- Study order
- 2
- Run
- Single-file source launch
- Command
- java pkg18resiliencepatterns/resilience2RetryWithBackoff.java
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg18resiliencepatterns;2 3import java.time.Duration;4import java.util.concurrent.ThreadLocalRandom;5import java.util.function.Supplier;6 7/*8 * resilience2RetryWithBackoff.java9 * --------------------------------10 * Retry with exponential backoff + jitter: recover from transient failures.11 *12 * DEFINITION:13 * Retry re-executes a failed operation. Backoff increases delay between tries;14 * jitter randomizes delay to prevent synchronized retries (thundering herd).15 *16 * KEY POINTS:17 * - Only retry transient errors (timeouts, 503), not business failures.18 * - Cap max attempts and max delay.19 * - Idempotent operations are safe to retry.20 */21public class resilience2RetryWithBackoff {22 23 static <T> T retry(Supplier<T> action, int maxAttempts, Duration initialDelay, Duration maxDelay) {24 Duration delay = initialDelay;25 for (int attempt = 1; attempt <= maxAttempts; attempt++) {26 try {27 return action.get();28 } catch (RuntimeException e) {29 if (attempt == maxAttempts) throw e;30 long jitter = ThreadLocalRandom.current().nextLong(delay.toMillis() / 2, delay.toMillis());31 System.out.printf(" attempt %d failed (%s), retry in %d ms%n", attempt, e.getMessage(), jitter);32 try { Thread.sleep(jitter); } catch (InterruptedException ie) {33 Thread.currentThread().interrupt();34 throw new RuntimeException(ie);35 }36 delay = Duration.ofMillis(Math.min(delay.toMillis() * 2, maxDelay.toMillis()));37 }38 }39 throw new IllegalStateException("unreachable");40 }41 42 public static void main(String[] args) {43 java.util.concurrent.atomic.AtomicInteger calls = new java.util.concurrent.atomic.AtomicInteger();44 45 String result = retry(() -> {46 int n = calls.incrementAndGet();47 if (n <= 2) throw new RuntimeException("timeout");48 return "ok on attempt " + n;49 }, 5, Duration.ofMillis(50), Duration.ofMillis(400));50 51 System.out.println("Result: " + result);52 }53}