Record Class Retry<T>
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.-
Nested Class Summary
Nested classes/interfaces inherited from interface io.github.teceli.resiliencia.core.api.Resilient
Resilient.Operation<T> -
Constructor Summary
ConstructorsConstructorDescriptionRetry(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 aRetryrecord class. -
Method Summary
Modifier and TypeMethodDescriptiondoubleReturns the value of thebackoffMultiplierrecord component.call(Resilient.Operation<T> operation) Execute an operation with resilience guarantees.clock()Returns the value of theclockrecord component.static <T> Retry<T> ARetryinstance configured with sensible defaults, ready to use as-is or refine further viawithXmethods.final booleanIndicates whether some other object is "equal to" this one.final inthashCode()Returns a hash code value for this object.booleanTrue oncewithOverallDeadline(long)has been configured, telling Policy this Retry already caps its own total duration.longReturns the value of theinitialDelayMsrecord component.doubleReturns the value of thejitterFactorrecord component.Returns the value of thelistenersrecord component.intReturns the value of themaxAttemptsrecord component.longReturns the value of themaxDelayMsrecord component.name()Returns the value of thenamerecord component.outcome(Resilient.Operation<T> operation) Execute an operation and capture the result or failure as an Outcome.Returns the value of theoverallDeadlinerecord component.The kind of this pattern, used for internal comparisons (e.g.The name of this pattern, e.g.Returns the value of theshouldRetryrecord component.final StringtoString()Returns a string representation of this record class.withBackoffMultiplier(double multiplier) Factor each backoff delay is multiplied by after every failed attempt, producing exponential growth fromwithInitialDelay(long).Use a customClockinstead of the system clock, e.g. a manual/virtual clock in tests to make backoff assertions deterministic and instant.withInitialDelay(long delayMs) Delay before the first retry attempt.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).withListener(ResilienceEvent.Listener listener) Add a listener notified of everyRetryEventemitted by this instance.withMaxAttempts(int maxAttempts) Maximum number of attempts, including the first one —withMaxAttempts(1)disables retrying entirely.withMaxDelay(long maxDelayMs) Cap every backoff delay (including the initial one, after jitter) at the given value, preventing unbounded exponential growth.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.withShouldRetry(Predicate<Throwable> predicate) Decide, for each thrown exception, whether it is worth retrying.
-
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 aRetryrecord class.- Parameters:
name- the value for thenamerecord componentmaxAttempts- the value for themaxAttemptsrecord componentinitialDelayMs- the value for theinitialDelayMsrecord componentbackoffMultiplier- the value for thebackoffMultiplierrecord componentmaxDelayMs- the value for themaxDelayMsrecord componentjitterFactor- the value for thejitterFactorrecord componentoverallDeadline- the value for theoverallDeadlinerecord componentshouldRetry- the value for theshouldRetryrecord componentlisteners- the value for thelistenersrecord componentclock- the value for theclockrecord component
-
-
Method Details
-
create
ARetryinstance configured with sensible defaults, ready to use as-is or refine further viawithXmethods. By default, retries only onIOExceptionand its subclasses, which are assumed to be transient (network errors, timeouts, connection resets). Other exceptions are treated as permanent failures. To customize, usewithShouldRetry(Predicate).- Parameters:
name- identifier used in everyRetryEventemitted by this instance. Not enforced unique across instances — there is no global registry to check against.
-
withMaxAttempts
Maximum number of attempts, including the first one —withMaxAttempts(1)disables retrying entirely. Must be at least 1. Default: 3. -
withInitialDelay
Delay before the first retry attempt. Subsequent delays grow from this base according towithBackoffMultiplier(double). Must be at least 0. Default: 100ms. -
withBackoffMultiplier
Factor each backoff delay is multiplied by after every failed attempt, producing exponential growth fromwithInitialDelay(long). Must be at least 1.0 (1.0 means a constant delay, no growth). Default: 2.0. -
withMaxDelay
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
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
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 (emitsRetryEvent.Exhaustedand throwsRetryExhaustedException), even ifmaxAttemptshas not been reached yet. Disabled (uncapped) by default. -
withShouldRetry
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 asfalse— a broken predicate rejects the retry instead of replacing the real exception. Default: retries onlyIOExceptionand its subclasses. -
withListener
Add a listener notified of everyRetryEventemitted by this instance. Listener exceptions are logged and otherwise ignored — a broken listener never affects the outcome. -
withClock
Use a customClockinstead of the system clock, e.g. a manual/virtual clock in tests to make backoff assertions deterministic and instant. -
patternName
Description copied from interface:ResilientThe 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:
patternNamein interfaceResilient<T>
-
patternKind
Description copied from interface:ResilientThe kind of this pattern, used for internal comparisons (e.g. Policy order validation). UnlikeResilient.patternName(), which is a free-form observability label, this is a closed enum the library can reason about exhaustively. Defaults toPatternKind.CUSTOMfor user-defined Resilient implementations.- Specified by:
patternKindin interfaceResilient<T>
-
hasOwnDeadline
public boolean hasOwnDeadline()True oncewithOverallDeadline(long)has been configured, telling Policy this Retry already caps its own total duration.- Specified by:
hasOwnDeadlinein interfaceResilient<T>
-
call
Description copied from interface:ResilientExecute an operation with resilience guarantees. May throw ResilienciaException or a specific pattern exception.- Specified by:
callin interfaceResilient<T>- Throws:
ResilientException
-
outcome
Description copied from interface:ResilientExecute an operation and capture the result or failure as an Outcome. Never throws for a recordedException— always returns Success, Failure, or a pattern-specific outcome. AnErrorthrown 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. -
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. -
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. -
equals
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 withObjects::equals(Object,Object); primitive components are compared with '=='. -
name
Returns the value of thenamerecord component.- Returns:
- the value of the
namerecord component
-
maxAttempts
public int maxAttempts()Returns the value of themaxAttemptsrecord component.- Returns:
- the value of the
maxAttemptsrecord component
-
initialDelayMs
public long initialDelayMs()Returns the value of theinitialDelayMsrecord component.- Returns:
- the value of the
initialDelayMsrecord component
-
backoffMultiplier
public double backoffMultiplier()Returns the value of thebackoffMultiplierrecord component.- Returns:
- the value of the
backoffMultiplierrecord component
-
maxDelayMs
public long maxDelayMs()Returns the value of themaxDelayMsrecord component.- Returns:
- the value of the
maxDelayMsrecord component
-
jitterFactor
public double jitterFactor()Returns the value of thejitterFactorrecord component.- Returns:
- the value of the
jitterFactorrecord component
-
overallDeadline
Returns the value of theoverallDeadlinerecord component.- Returns:
- the value of the
overallDeadlinerecord component
-
shouldRetry
Returns the value of theshouldRetryrecord component.- Returns:
- the value of the
shouldRetryrecord component
-
listeners
Returns the value of thelistenersrecord component.- Returns:
- the value of the
listenersrecord component
-
clock
Returns the value of theclockrecord component.- Returns:
- the value of the
clockrecord component
-