Browse Source

Polish resilience features

pull/35603/head
Sam Brannen 2 months ago
parent
commit
58940794cf
  1. 11
      framework-docs/modules/ROOT/pages/core/resilience.adoc
  2. 2
      spring-context/src/main/java/org/springframework/resilience/annotation/ConcurrencyLimitBeanPostProcessor.java
  3. 12
      spring-context/src/main/java/org/springframework/resilience/annotation/Retryable.java
  4. 4
      spring-core/src/main/java/org/springframework/core/retry/RetryPolicy.java

11
framework-docs/modules/ROOT/pages/core/resilience.adoc

@ -40,6 +40,17 @@ public void sendNotification() { @@ -40,6 +40,17 @@ public void sendNotification() {
NOTE: `@Retryable(MessageDeliveryException.class)` is a shortcut for
`@Retryable(includes{nbsp}={nbsp}MessageDeliveryException.class)`.
[TIP]
====
For advanced use cases, you can specify a custom `MethodRetryPredicate` via the
`predicate` attribute in `@Retryable`, and the predicate will be used to determine whether
to retry a failed method invocation based on a `Method` and a given `Throwable` – for
example, by checking the message of the `Throwable`.
Custom predicates can be combined with `includes` and `excludes`; however, custom
predicates will always be applied after `includes` and `excludes` have been applied.
====
Or for 5 retry attempts and an exponential back-off strategy with a bit of jitter:
[source,java,indent=0,subs="verbatim,quotes"]

2
spring-context/src/main/java/org/springframework/resilience/annotation/ConcurrencyLimitBeanPostProcessor.java

@ -82,7 +82,7 @@ public class ConcurrencyLimitBeanPostProcessor extends AbstractBeanFactoryAwareA @@ -82,7 +82,7 @@ public class ConcurrencyLimitBeanPostProcessor extends AbstractBeanFactoryAwareA
Object target = invocation.getThis();
Class<?> targetClass = (target != null ? target.getClass() : method.getDeclaringClass());
if (target == null && invocation instanceof ProxyMethodInvocation methodInvocation) {
// Allow validation for AOP proxy without a target
// Support concurrency throttling for AOP proxy without a target
target = methodInvocation.getProxy();
}
Assert.state(target != null, "Target must not be null");

12
spring-context/src/main/java/org/springframework/resilience/annotation/Retryable.java

@ -64,6 +64,8 @@ public @interface Retryable { @@ -64,6 +64,8 @@ public @interface Retryable {
/**
* Applicable exception types to attempt a retry for. This attribute
* allows for the convenient specification of assignable exception types.
* <p>This can optionally be combined with {@link #excludes() excludes} or
* a custom {@link #predicate() predicate}.
* <p>The default is empty, leading to a retry attempt for any exception.
* @see #excludes()
* @see #predicate()
@ -74,6 +76,8 @@ public @interface Retryable { @@ -74,6 +76,8 @@ public @interface Retryable {
/**
* Non-applicable exception types to avoid a retry for. This attribute
* allows for the convenient specification of assignable exception types.
* <p>This can optionally be combined with {@link #includes() includes} or
* a custom {@link #predicate() predicate}.
* <p>The default is empty, leading to a retry attempt for any exception.
* @see #includes()
* @see #predicate()
@ -81,12 +85,14 @@ public @interface Retryable { @@ -81,12 +85,14 @@ public @interface Retryable {
Class<? extends Throwable>[] excludes() default {};
/**
* A predicate for filtering applicable exceptions for which
* an invocation can be retried.
* <p>The default is a retry attempt for any exception.
* A predicate for filtering applicable exceptions for which an invocation can
* be retried.
* <p>A specified {@link MethodRetryPredicate} implementation will be instantiated
* per method. It can use dependency injection at the constructor level or through
* autowiring annotations, in case it needs access to other beans or facilities.
* <p>This can optionally be combined with {@link #includes() includes} or
* {@link #excludes() excludes}.
* <p>The default is a retry attempt for any exception.
* @see #includes()
* @see #excludes()
*/

4
spring-core/src/main/java/org/springframework/core/retry/RetryPolicy.java

@ -80,8 +80,8 @@ public interface RetryPolicy { @@ -80,8 +80,8 @@ public interface RetryPolicy {
/**
* Create a {@link RetryPolicy} configured with a maximum number of retry attempts.
* <p>The returned policy uses a fixed backoff of {@value Builder#DEFAULT_DELAY}
* milliseconds.
* <p>The returned policy applies to all exception types and uses a fixed backoff
* of {@value Builder#DEFAULT_DELAY} milliseconds.
* @param maxAttempts the maximum number of retry attempts;
* must be positive (or zero for no retry)
* @see Builder#maxAttempts(long)

Loading…
Cancel
Save