Class RetryBackoffSpec
Retry strategy based on exponential backoffs, with configurable features. Use Retry.backoff(long, Duration)
to obtain a preconfigured instance to start with.
Retry delays are randomized with a user-provided jitter(double) factor between 0.d (no jitter)
and 1.0 (default is 0.5).
Even with the jitter, the effective backoff delay cannot be less than minBackoff(Duration)
nor more than maxBackoff(Duration). The delays and subsequent attempts are executed on the
provided backoff scheduler(Scheduler). Alternatively, Retry.fixedDelay(long, Duration) provides
a strategy where the min and max backoffs are the same and jitters are deactivated.
Only errors that match the filter(Predicate) are retried (by default all),
and the number of attempts can also limited with maxAttempts(long).
When the maximum attempt of retries is reached, a runtime exception is propagated downstream which
can be pinpointed with Exceptions.isRetryExhausted(Throwable). The cause of
the last attempt's failure is attached as said retryExhausted
exception's cause. This can be customized with onRetryExhaustedThrow(BiFunction).
Additionally, to help dealing with bursts of transient errors in a long-lived Flux as if each burst
had its own backoff, one can choose to set transientErrors(boolean) to true.
The comparison to maxAttempts(long) will then be done with the number of subsequent attempts
that failed without an onNext in between.
The RetryBackoffSpec is copy-on-write and as such can be stored as a "template" and further configured
by different components without a risk of modifying the original configuration.
- Author:
- Simon Baslé
-
Nested Class Summary
Nested classes/interfaces inherited from class reactor.util.retry.Retry
Retry.RetrySignal -
Field Summary
FieldsModifier and TypeFieldDescriptionThe configuredPredicateto filter which exceptions to retry.final booleanThe configured transient error handling flag.final doubleThe configured jitter factor, as adouble.final longThe configured maximum for retry attempts.final DurationThe configured maximum backoffDuration.final DurationThe configured minimum backoffDuration.final doubleThe configured multiplier, as adouble.Fields inherited from class reactor.util.retry.Retry
retryContext -
Method Summary
Modifier and TypeMethodDescriptiondoAfterRetry(Consumer<Retry.RetrySignal> doAfterRetry) Add synchronous behavior to be executed after the retry trigger is emitted in the companion publisher.doAfterRetryAsync(Function<Retry.RetrySignal, Mono<Void>> doAsyncAfterRetry) Add asynchronous behavior to be executed after the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additionalMono.doBeforeRetry(Consumer<Retry.RetrySignal> doBeforeRetry) Add synchronous behavior to be executed before the retry trigger is emitted in the companion publisher.doBeforeRetryAsync(Function<Retry.RetrySignal, Mono<Void>> doAsyncBeforeRetry) Add asynchronous behavior to be executed before the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additionalMono.Set thePredicatethat will filter which errors can be retried.Generates the companion publisher responsible for reacting to incomingRetry.RetrySignalemissions, effectively deciding when to retry.jitter(double jitterFactor) Set a jitter factor for exponential backoffs that adds randomness to each backoff.maxAttempts(long maxAttempts) Set the maximum number of retry attempts allowed.maxBackoff(Duration maxBackoff) Set a hard maximumDurationfor exponential backoffs.minBackoff(Duration minBackoff) Set the minimumDurationfor the first backoff.multiplier(double multiplier) Set a multiplier for exponential backoffs that is used as the base for each backoff.onRetryExhaustedThrow(BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator) Set the generator for theExceptionto be propagated when the maximum amount of retries is exhausted.Set aScheduleron which to execute the delays computed by the exponential backoff strategy.transientErrors(boolean isTransientErrors) Set the transient error mode, indicating that the strategy being built should useRetry.RetrySignal.totalRetriesInARow()rather thanRetry.RetrySignal.totalRetries().protected voidwithRetryContext(ContextView retryContext) Set the user providedcontextthat can be used to manipulate state on retries.Methods inherited from class reactor.util.retry.Retry
backoff, fixedDelay, from, indefinitely, max, maxInARow, retryContext, withThrowable
-
Field Details
-
minBackoff
The configured minimum backoffDuration.- See Also:
-
maxBackoff
The configured maximum backoffDuration.- See Also:
-
multiplier
public final double multiplierThe configured multiplier, as adouble.- See Also:
-
jitterFactor
public final double jitterFactorThe configured jitter factor, as adouble.- See Also:
-
backoffSchedulerSupplier
- See Also:
-
maxAttempts
public final long maxAttemptsThe configured maximum for retry attempts.- See Also:
-
errorFilter
The configuredPredicateto filter which exceptions to retry.- See Also:
-
isTransientErrors
public final boolean isTransientErrorsThe configured transient error handling flag.- See Also:
-
-
Method Details
-
withRetryContext
Set the user providedcontextthat can be used to manipulate state on retries.- Parameters:
retryContext- a new snapshot of user provided data- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
maxAttempts
Set the maximum number of retry attempts allowed. 1 meaning "1 retry attempt": the original subscription plus an extra re-subscription in case of an error, but no more.- Parameters:
maxAttempts- the new retry attempt limit- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
filter
Set thePredicatethat will filter which errors can be retried. Exceptions that don't pass the predicate will be propagated downstream and terminate the retry sequence. Defaults to allowing retries for all exceptions.- Parameters:
errorFilter- the predicate to filter which exceptions can be retried- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
modifyErrorFilter
public RetryBackoffSpec modifyErrorFilter(Function<Predicate<Throwable>, Predicate<? super Throwable>> predicateAdjuster) Allows to augment a previouslysetPredicatewith a new condition to allow retries of some exception or not. This can typically be used withPredicate.and(Predicate)to combine existing predicate(s) with a new one.For example:
//given RetrySpec retryTwiceIllegalArgument = Retry.max(2) .filter(e -> e instanceof IllegalArgumentException); RetrySpec retryTwiceIllegalArgWithCause = retryTwiceIllegalArgument.modifyErrorFilter(old -> old.and(e -> e.getCause() != null));- Parameters:
predicateAdjuster- aFunctionthat returns a newPredicategiven the currently in placePredicate(usually deriving from the old predicate).- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
doBeforeRetry
Add synchronous behavior to be executed before the retry trigger is emitted in the companion publisher. This should not be blocking, as the companion publisher might be executing in a shared thread.- Parameters:
doBeforeRetry- the synchronous hook to execute before retry trigger is emitted- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry - See Also:
-
doAfterRetry
Add synchronous behavior to be executed after the retry trigger is emitted in the companion publisher. This should not be blocking, as the companion publisher might be publishing events in a shared thread.- Parameters:
doAfterRetry- the synchronous hook to execute after retry trigger is started- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry - See Also:
-
doBeforeRetryAsync
public RetryBackoffSpec doBeforeRetryAsync(Function<Retry.RetrySignal, Mono<Void>> doAsyncBeforeRetry) Add asynchronous behavior to be executed before the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additionalMono.- Parameters:
doAsyncBeforeRetry- the asynchronous hook to execute before original retry trigger is emitted- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
doAfterRetryAsync
Add asynchronous behavior to be executed after the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additionalMono.- Parameters:
doAsyncAfterRetry- the asynchronous hook to execute after original retry trigger is emitted- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
onRetryExhaustedThrow
public RetryBackoffSpec onRetryExhaustedThrow(BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator) Set the generator for theExceptionto be propagated when the maximum amount of retries is exhausted. By default, throws anExceptions.retryExhausted(String, Throwable)with the message reflecting the total attempt index, transient attempt index and maximum retry count. The cause of the lastRetry.RetrySignalis also added as the exception's cause.- Parameters:
retryExhaustedGenerator- theFunctionthat generates theThrowablefor the lastRetry.RetrySignal- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
transientErrors
Set the transient error mode, indicating that the strategy being built should useRetry.RetrySignal.totalRetriesInARow()rather thanRetry.RetrySignal.totalRetries(). Transient errors are errors that could occur in bursts but are then recovered from by a retry (with one or more onNext signals) before another error occurs.For a backoff based retry, the backoff is also computed based on the index within the burst, meaning the next error after a recovery will be retried with a
minBackoff(Duration)delay.- Parameters:
isTransientErrors-trueto activate transient mode- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
minBackoff
Set the minimumDurationfor the first backoff. This method switches to an exponential backoff strategy if not already done so. Defaults toDuration.ZEROwhen the strategy was initially not a backoff one.- Parameters:
minBackoff- the minimum backoffDuration- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
maxBackoff
Set a hard maximumDurationfor exponential backoffs. This method switches to an exponential backoff strategy with a zero minimum backoff if not already a backoff strategy. Defaults toDuration.ofMillis(Long.MAX_VALUE).- Parameters:
maxBackoff- the maximum backoffDuration- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
jitter
Set a jitter factor for exponential backoffs that adds randomness to each backoff. This can be helpful in reducing cascading failure due to retry-storms. This method switches to an exponential backoff strategy with a zero minimum backoff if not already a backoff strategy. Defaults to0.5(a jitter of at most 50% of the computed delay).- Parameters:
jitterFactor- the new jitter factor as adoublebetween0dand1d- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
multiplier
Set a multiplier for exponential backoffs that is used as the base for each backoff. This method switches to an exponential backoff strategy with a zero minimum backoff if not already a backoff strategy. Defaults to2.- Parameters:
multiplier- the new multiplier as adouble- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
scheduler
Set aScheduleron which to execute the delays computed by the exponential backoff strategy. Defaults to a deferred resolution of the currentSchedulers.parallel()(usenullto reset to this default).- Parameters:
backoffScheduler- theSchedulerto use, ornullto revert to the default- Returns:
- a new copy of the
RetryBackoffSpecwhich can either be further configured or used asRetry
-
validateArguments
protected void validateArguments() -
generateCompanion
Description copied from class:RetryGenerates the companion publisher responsible for reacting to incomingRetry.RetrySignalemissions, effectively deciding when to retry.When the source signals an error, that
onErrorsignal will be suppressed. ItsThrowablewill instead be attached to aRetry.RetrySignal, immediately emitted on theretrySignalspublisher. Right after that emission,request(1)is called on the companion publisher.The response to that request decides if a retry should be made. Thus, the outer publisher will wait until a signal is emitted by the companion publisher, making it possible to delay retry attempts.
Any
onNextemitted by the companion publisher triggers a retry,onErrorwill fail the outer publisher andonCompletewill complete the outer publisher (effectively suppressing the original error/Throwable).As an example, the simplest form of retry companion would be to return the incoming
FluxofRetry.RetrySignalwithout modification. This would render a retry strategy that immediately retries, forever.- Specified by:
generateCompanionin classRetry- Parameters:
t- the errors from the outer publisher asRetry.RetrySignalobjects, containing theThrowablecausing the error as well as retry counter metadata.- Returns:
- the companion publisher responsible for reacting to incoming
Retry.RetrySignalemissions, effectively deciding when to retry.
-