java.lang.Object
java.lang.Record
io.github.teceli.resiliencia.patterns.retry.Retry<T>
All Implemented Interfaces:
Resilient<T>

public record Retry<T>(String name, int maxAttempts, long initialDelayMs, double backoffMultiplier, long maxDelayMs, double jitterFactor, OptionalLong overallDeadline, Predicate<Throwable> shouldRetry, List<ResilienceEvent.Listener> listeners, Clock clock) extends Record implements Resilient<T>
Retry pattern: execute an operation, retrying on failure up to maxAttempts. Supports exponential backoff with an optional max-delay cap and jitter, and conditional retry (filter which exceptions to retry). Immutable and reusable: each withX method returns a new, independently usable Retry instance rather than mutating this one.
  • Constructor Details

    • Retry

      public Retry(String name, int maxAttempts, long initialDelayMs, double backoffMultiplier, long maxDelayMs, double jitterFactor, OptionalLong overallDeadline, Predicate<Throwable> shouldRetry, List<ResilienceEvent.Listener> listeners, Clock clock)
      Creates an instance of a Retry record class.
      Parameters:
      name - the value for the name record component
      maxAttempts - the value for the maxAttempts record component
      initialDelayMs - the value for the initialDelayMs record component
      backoffMultiplier - the value for the backoffMultiplier record component
      maxDelayMs - the value for the maxDelayMs record component
      jitterFactor - the value for the jitterFactor record component
      overallDeadline - the value for the overallDeadline record component
      shouldRetry - the value for the shouldRetry record component
      listeners - the value for the listeners record component
      clock - the value for the clock record component
  • Method Details

    • create

      public static <T> Retry<T> create(String name)
      A Retry instance configured with sensible defaults, ready to use as-is or refine further via withX methods. By default, retries only on IOException and its subclasses, which are assumed to be transient (network errors, timeouts, connection resets). Other exceptions are treated as permanent failures. To customize, use withShouldRetry(Predicate).
      Parameters:
      name - identifier used in every RetryEvent emitted by this instance. Not enforced unique across instances — there is no global registry to check against.
    • withMaxAttempts

      public Retry<T> withMaxAttempts(int maxAttempts)
      Maximum number of attempts, including the first one — withMaxAttempts(1) disables retrying entirely. Must be at least 1. Default: 3.
    • withInitialDelay

      public Retry<T> withInitialDelay(long delayMs)
      Delay before the first retry attempt. Subsequent delays grow from this base according to withBackoffMultiplier(double). Must be at least 0. Default: 100ms.
    • withBackoffMultiplier

      public Retry<T> withBackoffMultiplier(double multiplier)
      Factor each backoff delay is multiplied by after every failed attempt, producing exponential growth from withInitialDelay(long). Must be at least 1.0 (1.0 means a constant delay, no growth). Default: 2.0.
    • withMaxDelay

      public Retry<T> withMaxDelay(long maxDelayMs)
      Cap every backoff delay (including the initial one, after jitter) at the given value, preventing unbounded exponential growth. Delays above the cap are clamped, not rejected.
    • withJitter

      public Retry<T> withJitter(double jitterFactor)
      Randomize each backoff delay uniformly within [delay * (1 - factor), delay * (1 + factor)] to spread out retries from many clients that failed at the same moment (thundering herd). A factor of 0.0 (the default) disables jitter; 1.0 allows anywhere from zero to double the delay.
    • withOverallDeadline

      public Retry<T> withOverallDeadline(long overallDeadlineMs)
      Bound the total wall-clock time this retry loop is willing to spend across all attempts and backoff waits, measured from the first attempt. Checked only between attempts — never preempts an attempt already in progress, which stays Timeout's responsibility. Once the deadline has passed, the loop stops as if the attempt budget were exhausted (emits RetryEvent.Exhausted and throws RetryExhaustedException), even if maxAttempts has not been reached yet. Disabled (uncapped) by default.
    • withShouldRetry

      public Retry<T> withShouldRetry(Predicate<Throwable> predicate)
      Decide, for each thrown exception, whether it is worth retrying. Evaluated once per failed attempt, before the attempt count and deadline are checked. If the predicate itself throws, that is logged as a warning and treated as false — a broken predicate rejects the retry instead of replacing the real exception. Default: retries only IOException and its subclasses.
    • withListener

      public Retry<T> withListener(ResilienceEvent.Listener listener)
      Add a listener notified of every RetryEvent emitted by this instance. Listener exceptions are logged and otherwise ignored — a broken listener never affects the outcome.
    • withClock

      public Retry<T> withClock(Clock clock)
      Use a custom Clock instead of the system clock, e.g. a manual/virtual clock in tests to make backoff assertions deterministic and instant.
    • patternName

      public String patternName()
      Description copied from interface: Resilient
      The name of this pattern, e.g. "retry", "timeout", "circuit-breaker". Used for identification (e.g. by Policy) without coupling to concrete pattern types. Defaults to "custom" for user-defined Resilient implementations.
      Specified by:
      patternName in interface Resilient<T>
    • patternKind

      public PatternKind patternKind()
      Description copied from interface: Resilient
      The kind of this pattern, used for internal comparisons (e.g. Policy order validation). Unlike Resilient.patternName(), which is a free-form observability label, this is a closed enum the library can reason about exhaustively. Defaults to PatternKind.CUSTOM for user-defined Resilient implementations.
      Specified by:
      patternKind in interface Resilient<T>
    • hasOwnDeadline

      public boolean hasOwnDeadline()
      True once withOverallDeadline(long) has been configured, telling Policy this Retry already caps its own total duration.
      Specified by:
      hasOwnDeadline in interface Resilient<T>
    • call

      public T call(Resilient.Operation<T> operation) throws ResilientException
      Description copied from interface: Resilient
      Execute an operation with resilience guarantees. May throw ResilienciaException or a specific pattern exception.
      Specified by:
      call in interface Resilient<T>
      Throws:
      ResilientException
    • outcome

      public Outcome<T> outcome(Resilient.Operation<T> operation)
      Description copied from interface: Resilient
      Execute an operation and capture the result or failure as an Outcome. Never throws for a recorded Exception — always returns Success, Failure, or a pattern-specific outcome. An Error thrown by the operation propagates uncaught instead of being captured as a Failure: fatal JVM conditions (e.g. OutOfMemoryError) should not be treated as a recoverable result.
      Specified by:
      outcome in interface Resilient<T>
    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. Reference components are compared with Objects::equals(Object,Object); primitive components are compared with '=='.
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • name

      public String name()
      Returns the value of the name record component.
      Returns:
      the value of the name record component
    • maxAttempts

      public int maxAttempts()
      Returns the value of the maxAttempts record component.
      Returns:
      the value of the maxAttempts record component
    • initialDelayMs

      public long initialDelayMs()
      Returns the value of the initialDelayMs record component.
      Returns:
      the value of the initialDelayMs record component
    • backoffMultiplier

      public double backoffMultiplier()
      Returns the value of the backoffMultiplier record component.
      Returns:
      the value of the backoffMultiplier record component
    • maxDelayMs

      public long maxDelayMs()
      Returns the value of the maxDelayMs record component.
      Returns:
      the value of the maxDelayMs record component
    • jitterFactor

      public double jitterFactor()
      Returns the value of the jitterFactor record component.
      Returns:
      the value of the jitterFactor record component
    • overallDeadline

      public OptionalLong overallDeadline()
      Returns the value of the overallDeadline record component.
      Returns:
      the value of the overallDeadline record component
    • shouldRetry

      public Predicate<Throwable> shouldRetry()
      Returns the value of the shouldRetry record component.
      Returns:
      the value of the shouldRetry record component
    • listeners

      public List<ResilienceEvent.Listener> listeners()
      Returns the value of the listeners record component.
      Returns:
      the value of the listeners record component
    • clock

      public Clock clock()
      Returns the value of the clock record component.
      Returns:
      the value of the clock record component