Introduce java.time.Duration
* Introduce `java.time.Duration` variants into `RetryTemplateBuilder` * Fix non-null assertion messages
This commit is contained in:
committed by
GitHub
parent
daa04dbf1e
commit
41b7df83bb
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.retry.support;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -83,6 +84,7 @@ import org.springframework.util.Assert;
|
||||
* @author Aleksandr Shamukov
|
||||
* @author Artem Bilan
|
||||
* @author Kim In Hoi
|
||||
* @author Andreas Ahlenstorf
|
||||
* @since 1.3
|
||||
*/
|
||||
public class RetryTemplateBuilder {
|
||||
@@ -122,16 +124,43 @@ public class RetryTemplateBuilder {
|
||||
* @param timeout whole execution timeout in milliseconds
|
||||
* @return this
|
||||
* @see TimeoutRetryPolicy
|
||||
* @deprecated Use {@link #withTimeout(long)} instead.
|
||||
*/
|
||||
@Deprecated(since = "2.0.2", forRemoval = true)
|
||||
public RetryTemplateBuilder withinMillis(long timeout) {
|
||||
Assert.isTrue(timeout > 0, "Timeout should be positive");
|
||||
return withTimeout(timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry until {@code timeout} has passed since the initial attempt.
|
||||
* @param timeoutMillis timeout in milliseconds
|
||||
* @return this
|
||||
* @see TimeoutRetryPolicy
|
||||
* @throws IllegalArgumentException if timeout is {@literal <=} 0 or if another retry
|
||||
* policy has already been configured.
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder withTimeout(long timeoutMillis) {
|
||||
Assert.isTrue(timeoutMillis > 0, "timeoutMillis should be greater than 0");
|
||||
Assert.isNull(this.baseRetryPolicy, "You have already selected another retry policy");
|
||||
TimeoutRetryPolicy timeoutRetryPolicy = new TimeoutRetryPolicy();
|
||||
timeoutRetryPolicy.setTimeout(timeout);
|
||||
this.baseRetryPolicy = timeoutRetryPolicy;
|
||||
this.baseRetryPolicy = new TimeoutRetryPolicy(timeoutMillis);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry until {@code timeout} has passed since the initial attempt.
|
||||
* @param timeout duration for how long retries should be attempted
|
||||
* @return this
|
||||
* @see TimeoutRetryPolicy
|
||||
* @throws IllegalArgumentException if timeout is {@code null} or 0, or if another
|
||||
* retry policy has already been configured.
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder withTimeout(Duration timeout) {
|
||||
Assert.notNull(timeout, "timeout must not be null");
|
||||
return withTimeout(timeout.toMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows infinite retry, do not limit attempts by number or time.
|
||||
* <p>
|
||||
@@ -180,6 +209,27 @@ public class RetryTemplateBuilder {
|
||||
return exponentialBackoff(initialInterval, multiplier, maxInterval, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use exponential backoff policy. The formula of backoff period:
|
||||
* <p>
|
||||
* {@code currentInterval = Math.min(initialInterval * Math.pow(multiplier, retryNum), maxInterval)}
|
||||
* <p>
|
||||
* (for first attempt retryNum = 0)
|
||||
* @param initialInterval initial sleep duration
|
||||
* @param multiplier backoff interval multiplier
|
||||
* @param maxInterval maximum backoff duration
|
||||
* @return this
|
||||
* @see ExponentialBackOffPolicy
|
||||
* @throws IllegalArgumentException if initialInterval is {@code null}, multiplier is
|
||||
* {@literal <=} 1, or if maxInterval is {@code null}
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder exponentialBackoff(Duration initialInterval, double multiplier, Duration maxInterval) {
|
||||
Assert.notNull(initialInterval, "initialInterval must not be null");
|
||||
Assert.notNull(maxInterval, "maxInterval must not be null");
|
||||
return exponentialBackoff(initialInterval.toMillis(), multiplier, maxInterval.toMillis(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use exponential backoff policy. The formula of backoff period (without randomness):
|
||||
* <p>
|
||||
@@ -210,6 +260,31 @@ public class RetryTemplateBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use exponential backoff policy. The formula of backoff period (without randomness):
|
||||
* <p>
|
||||
* {@code currentInterval = Math.min(initialInterval * Math.pow(multiplier, retryNum), maxInterval)}
|
||||
* <p>
|
||||
* (for first attempt retryNum = 0)
|
||||
* @param initialInterval initial sleep duration
|
||||
* @param multiplier backoff interval multiplier
|
||||
* @param maxInterval maximum backoff duration
|
||||
* @param withRandom adds some randomness to backoff intervals. For details, see
|
||||
* {@link ExponentialRandomBackOffPolicy}
|
||||
* @return this
|
||||
* @see ExponentialBackOffPolicy
|
||||
* @see ExponentialRandomBackOffPolicy
|
||||
* @throws IllegalArgumentException if initialInterval is {@code null}, multiplier is
|
||||
* {@literal <=} 1, or maxInterval is {@code null}
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder exponentialBackoff(Duration initialInterval, double multiplier, Duration maxInterval,
|
||||
boolean withRandom) {
|
||||
Assert.notNull(initialInterval, "initialInterval most not be null");
|
||||
Assert.notNull(maxInterval, "maxInterval must not be null");
|
||||
return this.exponentialBackoff(initialInterval.toMillis(), multiplier, maxInterval.toMillis(), withRandom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform each retry after fixed amount of time.
|
||||
* @param interval fixed interval in milliseconds
|
||||
@@ -225,6 +300,24 @@ public class RetryTemplateBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform each retry after fixed amount of time.
|
||||
* @param interval fixed backoff duration
|
||||
* @return this
|
||||
* @see FixedBackOffPolicy
|
||||
* @throws IllegalArgumentException if another backoff policy has already been
|
||||
* configured, interval is {@code null} or less than 1 millisecond
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder fixedBackoff(Duration interval) {
|
||||
Assert.notNull(interval, "interval must not be null");
|
||||
|
||||
long millis = interval.toMillis();
|
||||
Assert.isTrue(millis >= 1, "interval is less than 1 millisecond");
|
||||
|
||||
return this.fixedBackoff(millis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link UniformRandomBackOffPolicy}, see it's doc for details.
|
||||
* @param minInterval in milliseconds
|
||||
@@ -244,6 +337,23 @@ public class RetryTemplateBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link UniformRandomBackOffPolicy}.
|
||||
* @param minInterval minimum backoff duration
|
||||
* @param maxInterval maximum backoff duration
|
||||
* @return this
|
||||
* @see UniformRandomBackOffPolicy
|
||||
* @throws IllegalArgumentException if minInterval is {@code null} or {@literal <} 1,
|
||||
* maxInterval is {@code null} or {@literal <} 1, maxInterval {@literal >=}
|
||||
* minInterval or if another backoff policy has already been configured.
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public RetryTemplateBuilder uniformRandomBackoff(Duration minInterval, Duration maxInterval) {
|
||||
Assert.notNull(minInterval, "minInterval must not be null");
|
||||
Assert.notNull(maxInterval, "maxInterval must not be null");
|
||||
return this.uniformRandomBackoff(minInterval.toMillis(), maxInterval.toMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not pause between attempts, retry immediately.
|
||||
* @return this
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.retry.support;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -29,6 +30,7 @@ import org.springframework.retry.RetryListener;
|
||||
import org.springframework.retry.RetryPolicy;
|
||||
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||
import org.springframework.retry.backoff.ExponentialRandomBackOffPolicy;
|
||||
import org.springframework.retry.backoff.FixedBackOffPolicy;
|
||||
import org.springframework.retry.backoff.NoBackOffPolicy;
|
||||
import org.springframework.retry.backoff.UniformRandomBackOffPolicy;
|
||||
import org.springframework.retry.policy.AlwaysRetryPolicy;
|
||||
@@ -53,6 +55,7 @@ import static org.springframework.retry.util.test.TestUtils.getPropertyValue;
|
||||
* @author Aleksandr Shamukov
|
||||
* @author Kim In Hoi
|
||||
* @author Gary Russell
|
||||
* @author Andreas Ahlenstorf
|
||||
*/
|
||||
public class RetryTemplateBuilderTests {
|
||||
|
||||
@@ -113,10 +116,11 @@ public class RetryTemplateBuilderTests {
|
||||
@Test
|
||||
public void testFailOnRetryPoliciesConflict() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> RetryTemplate.builder().maxAttempts(3).withinMillis(1000).build());
|
||||
.isThrownBy(() -> RetryTemplate.builder().maxAttempts(3).withTimeout(1000).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("removal")
|
||||
public void testTimeoutPolicy() {
|
||||
RetryTemplate template = RetryTemplate.builder().withinMillis(10000).build();
|
||||
|
||||
@@ -127,6 +131,28 @@ public class RetryTemplateBuilderTests {
|
||||
assertThat(((TimeoutRetryPolicy) policyTuple.baseRetryPolicy).getTimeout()).isEqualTo(10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeoutMillis() {
|
||||
RetryTemplate template = RetryTemplate.builder().withTimeout(10000).build();
|
||||
|
||||
PolicyTuple policyTuple = PolicyTuple.extractWithAsserts(template);
|
||||
assertDefaultClassifier(policyTuple);
|
||||
|
||||
assertThat(policyTuple.baseRetryPolicy).isInstanceOf(TimeoutRetryPolicy.class);
|
||||
assertThat(((TimeoutRetryPolicy) policyTuple.baseRetryPolicy).getTimeout()).isEqualTo(10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeoutDuration() {
|
||||
RetryTemplate template = RetryTemplate.builder().withTimeout(Duration.ofSeconds(3)).build();
|
||||
|
||||
PolicyTuple policyTuple = PolicyTuple.extractWithAsserts(template);
|
||||
assertDefaultClassifier(policyTuple);
|
||||
|
||||
assertThat(policyTuple.baseRetryPolicy).isInstanceOf(TimeoutRetryPolicy.class);
|
||||
assertThat(((TimeoutRetryPolicy) policyTuple.baseRetryPolicy).getTimeout()).isEqualTo(3000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInfiniteRetry() {
|
||||
RetryTemplate template = RetryTemplate.builder().infiniteRetry().build();
|
||||
@@ -190,24 +216,91 @@ public class RetryTemplateBuilderTests {
|
||||
.isThrownBy(() -> RetryTemplate.builder().noBackoff().fixedBackoff(1000).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedBackoff() {
|
||||
RetryTemplate template = RetryTemplate.builder().fixedBackoff(200).build();
|
||||
FixedBackOffPolicy policy = getPropertyValue(template, "backOffPolicy", FixedBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getBackOffPeriod()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedBackoffDuration() {
|
||||
RetryTemplate template = RetryTemplate.builder().fixedBackoff(Duration.ofSeconds(1)).build();
|
||||
FixedBackOffPolicy policy = getPropertyValue(template, "backOffPolicy", FixedBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getBackOffPeriod()).isEqualTo(1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniformRandomBackOff() {
|
||||
RetryTemplate template = RetryTemplate.builder().uniformRandomBackoff(10, 100).build();
|
||||
assertThat(getPropertyValue(template, "backOffPolicy")).isInstanceOf(UniformRandomBackOffPolicy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniformRandomBackOffDuration() {
|
||||
RetryTemplate template = RetryTemplate.builder()
|
||||
.uniformRandomBackoff(Duration.ofSeconds(1), Duration.ofSeconds(2))
|
||||
.build();
|
||||
|
||||
UniformRandomBackOffPolicy policy = getPropertyValue(template, "backOffPolicy",
|
||||
UniformRandomBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getMinBackOffPeriod()).isEqualTo(1000);
|
||||
assertThat(policy.getMaxBackOffPeriod()).isEqualTo(2000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoBackOff() {
|
||||
RetryTemplate template = RetryTemplate.builder().noBackoff().build();
|
||||
assertThat(getPropertyValue(template, "backOffPolicy")).isInstanceOf(NoBackOffPolicy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExponentialBackoff() {
|
||||
RetryTemplate template = RetryTemplate.builder().exponentialBackoff(10, 2, 500).build();
|
||||
ExponentialBackOffPolicy policy = getPropertyValue(template, "backOffPolicy", ExponentialBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getInitialInterval()).isEqualTo(10);
|
||||
assertThat(policy.getMultiplier()).isEqualTo(2);
|
||||
assertThat(policy.getMaxInterval()).isEqualTo(500);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExponentialBackoffDuration() {
|
||||
RetryTemplate template = RetryTemplate.builder()
|
||||
.exponentialBackoff(Duration.ofSeconds(2), 2, Duration.ofSeconds(3))
|
||||
.build();
|
||||
|
||||
ExponentialBackOffPolicy policy = getPropertyValue(template, "backOffPolicy", ExponentialBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getInitialInterval()).isEqualTo(2000);
|
||||
assertThat(policy.getMultiplier()).isEqualTo(2);
|
||||
assertThat(policy.getMaxInterval()).isEqualTo(3000);
|
||||
assertThat(policy.getMaxInterval()).isEqualTo(3000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpBackOffWithRandom() {
|
||||
RetryTemplate template = RetryTemplate.builder().exponentialBackoff(10, 2, 500, true).build();
|
||||
assertThat(getPropertyValue(template, "backOffPolicy")).isInstanceOf(ExponentialRandomBackOffPolicy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExponentialRandomBackoffDuration() {
|
||||
RetryTemplate template = RetryTemplate.builder()
|
||||
.exponentialBackoff(Duration.ofSeconds(2), 2, Duration.ofSeconds(3), true)
|
||||
.build();
|
||||
|
||||
ExponentialRandomBackOffPolicy policy = getPropertyValue(template, "backOffPolicy",
|
||||
ExponentialRandomBackOffPolicy.class);
|
||||
|
||||
assertThat(policy.getInitialInterval()).isEqualTo(2000);
|
||||
assertThat(policy.getMultiplier()).isEqualTo(2);
|
||||
assertThat(policy.getMaxInterval()).isEqualTo(3000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateInitAndMax() {
|
||||
assertThatIllegalArgumentException()
|
||||
|
||||
Reference in New Issue
Block a user