Top Description Fields Constructors Methods
reactor.util.retry

public final Class RetryBackoffSpec

extends Retry
Class Inheritance
Imports
java.time.Duration, java.util.Objects, java.util.concurrent.ThreadLocalRandom, java.util.function.BiFunction, .Consumer, .Function, .Predicate, .Supplier, reactor.core.Exceptions, reactor.core.publisher.Flux, .Mono, reactor.core.scheduler.Scheduler, .Schedulers, reactor.util.annotation.Nullable, reactor.util.context.Context, .ContextView

A 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 reactor.core.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é

Field Summary

Modifier and TypeField and Description
pack-priv final BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>>
pack-priv final BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>>
pack-priv static final BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable>
public final Supplier<Scheduler>
backoffSchedulerSupplier

The configured Supplier of Scheduler on which to execute backoffs.

public final Predicate<Throwable>
errorFilter

The configured Predicate to filter which exceptions to retry.

public final boolean
isTransientErrors

The configured transient error handling flag.

public final double
jitterFactor

The configured jitter factor, as a double.

public final long
maxAttempts

The configured maximum for retry attempts.

public final Duration
maxBackoff

The configured maximum backoff Duration.

public final Duration
minBackoff

The configured minimum backoff Duration.

pack-priv final BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable>
pack-priv final Consumer<Retry.RetrySignal>
pack-priv final Consumer<Retry.RetrySignal>
Inherited from reactor.util.retry.Retry:
retryContext

Constructor Summary

AccessConstructor and Description
pack-priv
RetryBackoffSpec(ContextView retryContext, long max, Predicate<? super Throwable> aThrowablePredicate, boolean isTransientErrors, Duration minBackoff, Duration maxBackoff, double jitterFactor, Supplier<Scheduler> backoffSchedulerSupplier, Consumer<Retry.RetrySignal> doPreRetry, Consumer<Retry.RetrySignal> doPostRetry, BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPreRetry, BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPostRetry, BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator)

Copy constructor.

Method Summary

Modifier and TypeMethod and Description
public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
doAfterRetry
(Consumer<Retry.RetrySignal>
the synchronous hook to execute after retry trigger is started
doAfterRetry
)

Add synchronous behavior to be executed after the retry trigger is emitted in the companion publisher.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
doAfterRetryAsync
(Function<Retry.RetrySignal, Mono<Void>>
the asynchronous hook to execute after original retry trigger is emitted
doAsyncAfterRetry
)

Add asynchronous behavior to be executed after the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additional Mono.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
doBeforeRetry
(Consumer<Retry.RetrySignal>
the synchronous hook to execute before retry trigger is emitted
doBeforeRetry
)

Add synchronous behavior to be executed before the retry trigger is emitted in the companion publisher.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
doBeforeRetryAsync
(Function<Retry.RetrySignal, Mono<Void>>
the asynchronous hook to execute before original retry trigger is emitted
doAsyncBeforeRetry
)

Add asynchronous behavior to be executed before the current retry trigger in the companion publisher, thus delaying the resulting retry trigger with the additional Mono.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
filter
(Predicate<? super Throwable>
the predicate to filter which exceptions can be retried
errorFilter
)

Set the Predicate that will filter which errors can be retried.

public Flux<Long>
generateCompanion(Flux<Retry.RetrySignal>
the errors from the outer publisher as RetrySignal objects, containing the Throwable causing the error as well as retry counter metadata.
t
)

Implements abstract reactor.util.retry.Retry.generateCompanion.

Generates the companion publisher responsible for reacting to incoming RetrySignal emissions, effectively deciding when to retry.
public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
jitter
(double
the new jitter factor as a double between 0d and 1d
jitterFactor
)

Set a jitter factor for exponential backoffs that adds randomness to each backoff.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
maxAttempts
(long
the new retry attempt limit
maxAttempts
)

Set the maximum number of retry attempts allowed.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
maxBackoff
(Duration
the maximum backoff Duration
maxBackoff
)

Set a hard maximum Duration for exponential backoffs.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
minBackoff
(Duration
the minimum backoff Duration
minBackoff
)

Set the minimum Duration for the first backoff.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
modifyErrorFilter
(Function<Predicate<Throwable>, Predicate<? super Throwable>>
a Function that returns a new Predicate given the currently in place Predicate (usually deriving from the old predicate).
predicateAdjuster
)

Allows to augment a previously set Predicate with a new condition to allow retries of some exception or not.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as reactor.util.retry.Retry
onRetryExhaustedThrow
(BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable>
the Function that generates the Throwable for the last reactor.util.retry.Retry.RetrySignal
retryExhaustedGenerator
)

Set the generator for the Exception to be propagated when the maximum amount of retries is exhausted.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
scheduler
(Scheduler
the Scheduler to use, or null to revert to the default
backoffScheduler
)

Set a Scheduler on which to execute the delays computed by the exponential backoff strategy.

public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
transientErrors
(boolean
true to activate transient mode
isTransientErrors
)

Set the transient error mode, indicating that the strategy being built should use reactor.util.retry.Retry.RetrySignal#totalRetriesInARow() rather than reactor.util.retry.Retry.RetrySignal#totalRetries().

protected void
public RetryBackoffSpec

Returns:

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry
withRetryContext
(ContextView
a new snapshot of user provided data
retryContext
)

Set the user provided context that can be used to manipulate state on retries.

Inherited from reactor.util.retry.Retry:
backofffixedDelayfromindefinitelymaxmaxInARowretryContextwithThrowable

Field Detail

asyncPostRetryback to summary
pack-priv final BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPostRetry
asyncPreRetryback to summary
pack-priv final BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPreRetry
BACKOFF_EXCEPTION_GENERATORback to summary
pack-priv static final BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> BACKOFF_EXCEPTION_GENERATOR
backoffSchedulerSupplierback to summary
public final Supplier<Scheduler> backoffSchedulerSupplier

The configured Supplier of Scheduler on which to execute backoffs.

See Also
scheduler(Scheduler)
errorFilterback to summary
public final Predicate<Throwable> errorFilter

The configured Predicate to filter which exceptions to retry.

See Also
filter(Predicate), modifyErrorFilter(Function)
isTransientErrorsback to summary
public final boolean isTransientErrors

The configured transient error handling flag.

See Also
transientErrors(boolean)
jitterFactorback to summary
public final double jitterFactor

The configured jitter factor, as a double.

See Also
jitter(double)
maxAttemptsback to summary
public final long maxAttempts

The configured maximum for retry attempts.

See Also
maxAttempts(long)
maxBackoffback to summary
public final Duration maxBackoff

The configured maximum backoff Duration.

See Also
maxBackoff(Duration)
minBackoffback to summary
public final Duration minBackoff

The configured minimum backoff Duration.

See Also
minBackoff(Duration)
retryExhaustedGeneratorback to summary
pack-priv final BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator
syncPostRetryback to summary
pack-priv final Consumer<Retry.RetrySignal> syncPostRetry
syncPreRetryback to summary
pack-priv final Consumer<Retry.RetrySignal> syncPreRetry

Constructor Detail

RetryBackoffSpecback to summary
pack-priv RetryBackoffSpec(ContextView retryContext, long max, Predicate<? super Throwable> aThrowablePredicate, boolean isTransientErrors, Duration minBackoff, Duration maxBackoff, double jitterFactor, Supplier<Scheduler> backoffSchedulerSupplier, Consumer<Retry.RetrySignal> doPreRetry, Consumer<Retry.RetrySignal> doPostRetry, BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPreRetry, BiFunction<Retry.RetrySignal, Mono<Void>, Mono<Void>> asyncPostRetry, BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator)

Copy constructor.

Method Detail

doAfterRetryback to summary
public RetryBackoffSpec doAfterRetry(Consumer<Retry.RetrySignal> 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:Consumer<Retry.RetrySignal>

the synchronous hook to execute after retry trigger is started

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

See Also
andRetryThen for an asynchronous version
doAfterRetryAsyncback to summary
public RetryBackoffSpec 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 additional Mono.

Parameters
doAsyncAfterRetry:Function<Retry.RetrySignal, Mono<Void>>

the asynchronous hook to execute after original retry trigger is emitted

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

doBeforeRetryback to summary
public RetryBackoffSpec doBeforeRetry(Consumer<Retry.RetrySignal> 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:Consumer<Retry.RetrySignal>

the synchronous hook to execute before retry trigger is emitted

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

See Also
andDelayRetryWith for an asynchronous version
doBeforeRetryAsyncback to summary
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 additional Mono.

Parameters
doAsyncBeforeRetry:Function<Retry.RetrySignal, Mono<Void>>

the asynchronous hook to execute before original retry trigger is emitted

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

filterback to summary
public RetryBackoffSpec filter(Predicate<? super Throwable> errorFilter)

Set the Predicate that 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:Predicate<? super Throwable>

the predicate to filter which exceptions can be retried

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

generateCompanionback to summary
public Flux<Long> generateCompanion(Flux<Retry.RetrySignal> t)

Implements abstract reactor.util.retry.Retry.generateCompanion.

Doc from reactor.util.retry.Retry.generateCompanion.

Generates the companion publisher responsible for reacting to incoming RetrySignal emissions, effectively deciding when to retry.

When the source signals an error, that onError signal will be suppressed. Its Throwable will instead be attached to a RetrySignal, immediately emitted on the retrySignals publisher. 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 onNext emitted by the companion publisher triggers a retry, onError will fail the outer publisher and onComplete will 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 Flux of RetrySignal without modification. This would render a retry strategy that immediately retries, forever.

Parameters
t:Flux<Retry.RetrySignal>

the errors from the outer publisher as RetrySignal objects, containing the Throwable causing the error as well as retry counter metadata.

Returns:Flux<Long>

the companion publisher responsible for reacting to incoming RetrySignal emissions, effectively deciding when to retry.

Annotations
@Override
jitterback to summary
public RetryBackoffSpec jitter(double jitterFactor)

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 to 0.5 (a jitter of at most 50% of the computed delay).

Parameters
jitterFactor:double

the new jitter factor as a double between 0d and 1d

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

maxAttemptsback to summary
public RetryBackoffSpec maxAttempts(long 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:long

the new retry attempt limit

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

maxBackoffback to summary
public RetryBackoffSpec maxBackoff(Duration maxBackoff)

Set a hard maximum Duration for exponential backoffs. This method switches to an exponential backoff strategy with a zero minimum backoff if not already a backoff strategy. Defaults to Duration.ofMillis(Long.MAX_VALUE).

Parameters
maxBackoff:Duration

the maximum backoff Duration

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

minBackoffback to summary
public RetryBackoffSpec minBackoff(Duration minBackoff)

Set the minimum Duration for the first backoff. This method switches to an exponential backoff strategy if not already done so. Defaults to Duration#ZERO when the strategy was initially not a backoff one.

Parameters
minBackoff:Duration

the minimum backoff Duration

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

modifyErrorFilterback to summary
public RetryBackoffSpec modifyErrorFilter(Function<Predicate<Throwable>, Predicate<? super Throwable>> predicateAdjuster)

Allows to augment a previously set Predicate with a new condition to allow retries of some exception or not. This can typically be used with Predicate#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:Function<Predicate<Throwable>, Predicate<? super Throwable>>

a Function that returns a new Predicate given the currently in place Predicate (usually deriving from the old predicate).

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

onRetryExhaustedThrowback to summary
public RetryBackoffSpec onRetryExhaustedThrow(BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable> retryExhaustedGenerator)

Set the generator for the Exception to be propagated when the maximum amount of retries is exhausted. By default, throws an Exceptions#retryExhausted(String, Throwable) with the message reflecting the total attempt index, transient attempt index and maximum retry count. The cause of the last reactor.util.retry.Retry.RetrySignal is also added as the exception's cause.

Parameters
retryExhaustedGenerator:BiFunction<RetryBackoffSpec, Retry.RetrySignal, Throwable>

the Function that generates the Throwable for the last reactor.util.retry.Retry.RetrySignal

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as reactor.util.retry.Retry

schedulerback to summary
public RetryBackoffSpec scheduler(Scheduler backoffScheduler)

Set a Scheduler on which to execute the delays computed by the exponential backoff strategy. Defaults to a deferred resolution of the current Schedulers#parallel() (use null to reset to this default).

Parameters
backoffScheduler:Scheduler

the Scheduler to use, or null to revert to the default

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

transientErrorsback to summary
public RetryBackoffSpec transientErrors(boolean isTransientErrors)

Set the transient error mode, indicating that the strategy being built should use reactor.util.retry.Retry.RetrySignal#totalRetriesInARow() rather than reactor.util.retry.Retry.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:boolean

true to activate transient mode

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry

validateArgumentsback to summary
protected void validateArguments()
withRetryContextback to summary
public RetryBackoffSpec withRetryContext(ContextView retryContext)

Set the user provided context that can be used to manipulate state on retries.

Parameters
retryContext:ContextView

a new snapshot of user provided data

Returns:RetryBackoffSpec

a new copy of the RetryBackoffSpec which can either be further configured or used as Retry