Class Retry

java.lang.Object
dev.fforj.Retry

public final class Retry extends Object
Retry policies for fallible operations.

Designed to be called from a virtual-thread context: Thread.sleep(Duration) is safe and cheap on virtual threads; no executor / scheduled task overhead.

Cancellation is structural: if the calling thread is interrupted (e.g. because a surrounding structured-concurrency scope shut down), the sleep throws InterruptedException and the retry loop bails immediately.

  • Method Details

    • run

      public static <E,T> Result<E,T> run(Retry.Policy policy, Predicate<? super E> shouldRetry, IntFunction<? extends Result<E,T>> body) throws InterruptedException
      Run body up to Retry.Policy.maxAttempts times until it succeeds, the error fails the shouldRetry predicate, or the caller's thread is interrupted.

      The body receives the current attempt number, starting at 1. The retry loop owns that counter, so callers never track it in outside mutable state. Use it for logging ("attempt 3 of 5 failed"), attempt-dependent behavior, or building it into the success value. When the number doesn't matter, use the Supplier overload.

      Parameters:
      policy - attempts, delay, backoff.
      shouldRetry - predicate over the error. Return true to retry on this error; false to surface immediately. Use this to distinguish transient failures (rate-limit, 5xx) from terminal ones (4xx, validation).
      body - the operation to run, given the 1-based attempt number. Must be effectively idempotent.
      Returns:
      the last Result produced. Always Ok on success; the most recent Err on exhaustion.
      Throws:
      InterruptedException - if the calling thread is interrupted during sleep.
    • run

      public static <E,T> Result<E,T> run(Retry.Policy policy, Predicate<? super E> shouldRetry, Supplier<? extends Result<E,T>> body) throws InterruptedException
      run, for bodies that don't care which attempt they're on.
      Throws:
      InterruptedException