Fixes retry filter retries on all operations when a response timeout occurs.

fixes gh-1372
fixes gh-1393
This commit is contained in:
Nikita Konev
2019-11-05 04:56:33 +03:00
committed by Spencer Gibb
parent 35eab962a1
commit fc7ed5b0a6
2 changed files with 38 additions and 3 deletions

View File

@@ -121,7 +121,10 @@ public class RetryGatewayFilterFactory
Retry<ServerWebExchange> exceptionRetry = null;
if (!retryConfig.getExceptions().isEmpty()) {
Predicate<RetryContext<ServerWebExchange>> retryContextPredicate = context -> {
if (exceedsMaxIterations(context.applicationContext(), retryConfig)) {
ServerWebExchange exchange = context.applicationContext();
if (exceedsMaxIterations(exchange, retryConfig)) {
return false;
}
@@ -133,7 +136,14 @@ public class RetryGatewayFilterFactory
trace("exception or its cause is retryable %s, configured exceptions %s",
() -> getExceptionNameWithCause(exception),
retryConfig::getExceptions);
return true;
HttpMethod httpMethod = exchange.getRequest().getMethod();
boolean retryableMethod = retryConfig.getMethods()
.contains(httpMethod);
trace("retryableMethod: %b, httpMethod %s, configured methods %s",
() -> retryableMethod, () -> httpMethod,
retryConfig::getMethods);
return retryableMethod;
}
}
trace("exception or its cause is not retryable %s, configured exceptions %s",

View File

@@ -147,6 +147,27 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
assertThat(TestConfig.map.get("sleepyRequest")).isNotNull().hasValue(3);
}
@Test
public void shouldNotRetryWhenSleepyRequestPost() throws Exception {
testClient.mutate().responseTimeout(Duration.ofSeconds(10)).build().post()
.uri("/sleep?key=notRetriesSleepyRequestPost&millis=3000")
.header(HttpHeaders.HOST, "www.retry-only-get.org").exchange()
.expectStatus().isEqualTo(HttpStatus.GATEWAY_TIMEOUT);
assertThat(TestConfig.map.get("notRetriesSleepyRequestPost")).isNotNull()
.hasValue(1);
}
@Test
public void shouldRetryWhenSleepyRequestGet() throws Exception {
testClient.mutate().responseTimeout(Duration.ofSeconds(10)).build().get()
.uri("/sleep?key=sleepyRequestGet&millis=3000")
.header(HttpHeaders.HOST, "www.retry-only-get.org").exchange()
.expectStatus().isEqualTo(HttpStatus.GATEWAY_TIMEOUT);
assertThat(TestConfig.map.get("sleepyRequestGet")).isNotNull().hasValue(3);
}
@Test
@SuppressWarnings("unchecked")
public void retryFilterLoadBalancedWithMultipleServers() {
@@ -252,7 +273,11 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
.retry(config -> config.setRetries(2)
.setMethods(HttpMethod.POST, HttpMethod.GET)))
.uri(uri))
.route("retry_only_get", r -> r.host("**.retry-only-get.org")
.filters(f -> f.prefixPath("/httpbin")
.retry(config -> config.setRetries(2)
.setMethods(HttpMethod.GET)))
.uri(uri))
.route("retry_with_backoff", r -> r.host("**.retrywithbackoff.org")
.filters(f -> f.prefixPath("/httpbin").retry(config -> {
config.setRetries(2).setBackoff(Duration.ofMillis(100),