diff --git a/core/spring-boot/src/main/java/org/springframework/boot/retry/RetryPolicySettings.java b/core/spring-boot/src/main/java/org/springframework/boot/retry/RetryPolicySettings.java index 6b406e2850c1..1eb3a96c3568 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/retry/RetryPolicySettings.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/retry/RetryPolicySettings.java @@ -56,6 +56,11 @@ public final class RetryPolicySettings { */ public static final Duration DEFAULT_MAX_DELAY = Duration.ofMillis(RetryPolicy.Builder.DEFAULT_MAX_DELAY); + /** + * Default maximum elapsed time (infinite). + */ + public static final Duration DEFAULT_TIMEOUT = RetryPolicy.withDefaults().getTimeout(); + private List> exceptionIncludes = new ArrayList<>(); private List> exceptionExcludes = new ArrayList<>(); @@ -72,6 +77,8 @@ public final class RetryPolicySettings { private Duration maxDelay = DEFAULT_MAX_DELAY; + private Duration timeout = DEFAULT_TIMEOUT; + private @Nullable Function factory; /** @@ -89,6 +96,7 @@ public RetryPolicy createRetryPolicy() { map.from(this::getJitter).to(builder::jitter); map.from(this::getMultiplier).to(builder::multiplier); map.from(this::getMaxDelay).to(builder::maxDelay); + map.from(this::getTimeout).to(builder::timeout); return (this.factory != null) ? this.factory.apply(builder) : builder.build(); } @@ -250,6 +258,29 @@ public void setMaxDelay(Duration maxDelay) { this.maxDelay = maxDelay; } + /** + * Return the timeout for the maximum amount of elapsed time allowed for the initial + * invocation and any subsequent retry attempts, including delays. + * @return the maximum duration the request can take + */ + public Duration getTimeout() { + return this.timeout; + } + + /** + * Specify a timeout for the maximum amount of elapsed time allowed for the initial + * invocation and any subsequent retry attempts, including delays. + *

+ * The default is {@link Duration#ZERO}, which signals that no timeout should be + * applied. + * @param timeout the timeout, typically in milliseconds or seconds; must be greater + * than or equal to zero + * @see #DEFAULT_TIMEOUT + */ + public void setTimeout(Duration timeout) { + this.timeout = timeout; + } + /** * Set the factory to use to create the {@link RetryPolicy}, or {@code null} to use * the default. The function takes a {@link Builder RetryPolicy.Builder} initialized diff --git a/core/spring-boot/src/test/java/org/springframework/boot/retry/RetryPolicySettingsTests.java b/core/spring-boot/src/test/java/org/springframework/boot/retry/RetryPolicySettingsTests.java index cd42a3734ba2..7254f7e31917 100644 --- a/core/spring-boot/src/test/java/org/springframework/boot/retry/RetryPolicySettingsTests.java +++ b/core/spring-boot/src/test/java/org/springframework/boot/retry/RetryPolicySettingsTests.java @@ -98,6 +98,11 @@ void getDefaultExceptionPredicate() { assertThat(new RetryPolicySettings().getExceptionPredicate()).isNull(); } + @Test + void getDefaultTimeout() { + assertThat(new RetryPolicySettings().getTimeout()).isEqualTo(RetryPolicy.withDefaults().getTimeout()); + } + @Test void createRetryPolicyWithExceptionPredicate() { IllegalArgumentException exception = new IllegalArgumentException("test");