Merge pull request #50891 from Chrisg2000

Closes gh-50891

* retrypolicy_timeout:
  Polish "Support timeout option in RetryPolicySettings"
  Support timeout option in RetryPolicySettings
This commit is contained in:
Stéphane Nicoll
2026-07-28 07:09:28 +02:00
2 changed files with 37 additions and 0 deletions
@@ -41,6 +41,12 @@ public final class RetryPolicySettings {
*/
public static final long DEFAULT_MAX_RETRIES = RetryPolicy.Builder.DEFAULT_MAX_RETRIES;
/**
* Default maximum elapsed time (infinite).
* @since 4.2.0
*/
public static final Duration DEFAULT_TIMEOUT = RetryPolicy.Builder.DEFAULT_TIMEOUT;
/**
* Default initial delay.
*/
@@ -64,6 +70,8 @@ public final class RetryPolicySettings {
private Long maxRetries = DEFAULT_MAX_RETRIES;
private Duration timeout = DEFAULT_TIMEOUT;
private Duration delay = DEFAULT_DELAY;
private @Nullable Duration jitter;
@@ -85,6 +93,7 @@ public final class RetryPolicySettings {
map.from(this::getExceptionExcludes).to(builder::excludes);
map.from(this::getExceptionPredicate).to(builder::predicate);
map.from(this::getMaxRetries).to(builder::maxRetries);
map.from(this::getTimeout).to(builder::timeout);
map.from(this::getDelay).to(builder::delay);
map.from(this::getJitter).to(builder::jitter);
map.from(this::getMultiplier).to(builder::multiplier);
@@ -168,6 +177,31 @@ public final class RetryPolicySettings {
this.maxRetries = maxRetries;
}
/**
* 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
* @since 4.2.0
*/
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.
* <p>
* 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
* @since 4.2.0
* @see #DEFAULT_TIMEOUT
*/
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
/**
* Return the base delay after the initial invocation.
* @return the base delay
@@ -115,6 +115,7 @@ class RetryPolicySettingsTests {
void createRetryPolicyWithDefaultsMatchesBackOffDefaults() {
RetryPolicy defaultRetryPolicy = RetryPolicy.builder().build();
RetryPolicy retryPolicy = new RetryPolicySettings().createRetryPolicy();
assertThat(retryPolicy.getTimeout()).isEqualByComparingTo(defaultRetryPolicy.getTimeout());
assertThat(retryPolicy.getBackOff()).isInstanceOf(ExponentialBackOff.class);
ExponentialBackOff defaultBackOff = (ExponentialBackOff) defaultRetryPolicy.getBackOff();
ExponentialBackOff backOff = (ExponentialBackOff) retryPolicy.getBackOff();
@@ -129,11 +130,13 @@ class RetryPolicySettingsTests {
void createRetryPolicyWithCustomAttributes() {
RetryPolicySettings settings = new RetryPolicySettings();
settings.setMaxRetries(10L);
settings.setTimeout(Duration.ofHours(1));
settings.setDelay(Duration.ofSeconds(2));
settings.setJitter(Duration.ofMillis(500));
settings.setMultiplier(2.0);
settings.setMaxDelay(Duration.ofSeconds(20));
RetryPolicy retryPolicy = settings.createRetryPolicy();
assertThat(retryPolicy.getTimeout()).isEqualTo(Duration.ofHours(1));
assertThat(retryPolicy.getBackOff()).isInstanceOfSatisfying(ExponentialBackOff.class, (backOff) -> {
assertThat(backOff.getMaxAttempts()).isEqualTo(10);
assertThat(backOff.getInitialInterval()).isEqualTo(2000);