Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

additional backoff strategies for retry #394

Closed
Ladicek opened this issue Mar 30, 2021 · 4 comments · Fixed by #449
Closed

additional backoff strategies for retry #394

Ladicek opened this issue Mar 30, 2021 · 4 comments · Fixed by #449
Milestone

Comments

@Ladicek
Copy link
Contributor

Ladicek commented Mar 30, 2021

We had a discussion about additional backoff strategies in MP FT a while ago, see eclipse/microprofile-fault-tolerance#220.

My opinion since then didn't change. @Retry is overcrowded and already includes one backoff strategy (constant delay) which has 4 (!!!) configuration attributes. Backoff strategies should be separated out of the @Retry annotation:

@Retry(maxRetries, maxDuration, maxDurationUnit, retryOn, abortOn)
@RetryWithConstantBackoff(delay, delayUnit, jitter, jitterUnit)
@RetryWithExponentialBackoff(initialDelay, initialDelayUnit, factor, [maxDelay, jitter, jitterUnit])
@RetryWithFibonacciBackoff(initialDelay, initialDelayUnit, [maxDelay, jitter, jitterUnit])
possibly others (polynomial, LILD, LIMD, MILD, MIMD, PLEB, PFB)

When only @Retry is used, there's no delay between retries. Adding one of the annotations above defines how individual retries should be delayed. Adding more than 1 is tricky to handle, because of the interactions between method-level and class-level annotations and inheritance, but that's a problem we already have.

We should prototype this approach here, in SmallRye, and see.

@Ladicek
Copy link
Contributor Author

Ladicek commented Jun 14, 2021

An interesting related discussion is #436. That would be solved by a custom backoff strategy, with one notable addition: the backoff strategy would have to have access to the causing exception. Something like:

@RetryWithCustomBackoff(MyCustomBackoffStrategy.class)

/**
 * One instance will be constructed for each invocation of a `@Retry` method
 * and will be used to compute delays between all retries. It is expected that
 * implementations will be stateful. It is possible that the `nextDelay` method
 * will be called from multiple threads, so implementations must be thread safe.
 * It is an error if implementations don't have a public zero-parameter constructor.
 */
interface BackoffStrategy {
    /**
     * @param ctx the failed method execution which requires a retry
     * @return next delay in millis
     */
    long nextDelay(ExecutionContext ctx);
}

This API doesn't allow declarative configuration of such custom backoff strategies, which is probably fine. Implementations can read configuration using MP Config in the constructor. Alternatively, the interface could also have an init method.

Open question: should implementations be CDI beans? I'm leaning towards no, but I don't have strong reasons for it.

@mhautman
Copy link

Hi @Ladicek,

What is the priority regarding this?
It's something we would really like to use.

@Ladicek
Copy link
Contributor Author

Ladicek commented Jun 18, 2021

This hasn't been a priority so far, but it seems more and more people ask for this. I'll try to get to it soon -- all the necessary building blocks are already there in the core, so it's just about implementing the BackOff interface, creating the annotations, plugging them into the config system, and wire everything together.

@Ladicek
Copy link
Contributor Author

Ladicek commented Jul 1, 2021

This was implemented in #449 as follows:

  • there's no new @Retry with limited set of attributes, we still keep using @Retry from MicroProfile Fault Tolerance (and all @Retry attributes are still used; notably, delay/delayUnit are used as an initial delay)
  • added @ExponentialBackoff, @FibonacciBackoff and @CustomBackoff that may be used together with @Retry (it's an error if one of the backoff annotations is used on a program element that doesn't have @Retry)

More info is in the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants