Skip to content

Commit b5a2e11

Browse files
authored
[java] Remove retrying on timeout exception (#13224)
* [java] Remove retrying on timeout exception Related to #12975
1 parent b59a9fb commit b5a2e11

File tree

2 files changed

+11
-93
lines changed

2 files changed

+11
-93
lines changed

java/src/org/openqa/selenium/remote/http/RetryRequest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
2121
import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT;
22-
import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT;
2322
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
2423
import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
2524
import static org.openqa.selenium.internal.Debug.getDebugLogLevel;
@@ -33,7 +32,6 @@
3332
import dev.failsafe.function.CheckedFunction;
3433
import java.net.ConnectException;
3534
import java.util.logging.Logger;
36-
import org.openqa.selenium.TimeoutException;
3735

3836
public class RetryRequest implements Filter {
3937

@@ -57,15 +55,6 @@ public class RetryRequest implements Filter {
5755
e.getAttemptCount()))
5856
.build();
5957

60-
// Retry on read timeout.
61-
private static final RetryPolicy<HttpResponse> readTimeoutPolicy =
62-
RetryPolicy.<HttpResponse>builder()
63-
.handle(TimeoutException.class)
64-
.withMaxRetries(3)
65-
.onRetry(
66-
e -> LOG.log(getDebugLogLevel(), "Read timeout #{0}. Retrying.", e.getAttemptCount()))
67-
.build();
68-
6958
// Retry if server is unavailable or an internal server error occurs without response body.
7059
private static final RetryPolicy<HttpResponse> serverErrorPolicy =
7160
RetryPolicy.<HttpResponse>builder()
@@ -88,7 +77,6 @@ public HttpHandler apply(HttpHandler next) {
8877
return req ->
8978
Failsafe.with(fallback)
9079
.compose(serverErrorPolicy)
91-
.compose(readTimeoutPolicy)
9280
.compose(connectionFailurePolicy)
9381
.get(() -> next.execute(req));
9482
}
@@ -102,11 +90,6 @@ private static HttpResponse getFallback(
10290
.setStatus(HTTP_CLIENT_TIMEOUT)
10391
.setContent(
10492
asJson(ImmutableMap.of("value", ImmutableMap.of("message", "Connection failure"))));
105-
} else if (exception instanceof TimeoutException) {
106-
return new HttpResponse()
107-
.setStatus(HTTP_GATEWAY_TIMEOUT)
108-
.setContent(
109-
asJson(ImmutableMap.of("value", ImmutableMap.of("message", "Read timeout"))));
11093
} else throw exception;
11194
} else if (executionAttemptedEvent.getLastResult() != null) {
11295
HttpResponse response = executionAttemptedEvent.getLastResult();

java/test/org/openqa/selenium/remote/http/RetryRequestTest.java

Lines changed: 11 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.openqa.selenium.remote.http;
1919

2020
import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT;
21-
import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT;
2221
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
2322
import static java.net.HttpURLConnection.HTTP_OK;
2423
import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
@@ -56,7 +55,8 @@ public void setUp() throws MalformedURLException {
5655
ClientConfig.defaultConfig()
5756
.baseUrl(URI.create("http://localhost:2345").toURL())
5857
.withRetries()
59-
.readTimeout(Duration.ofSeconds(1));
58+
.readTimeout(Duration.ofSeconds(1))
59+
.connectionTimeout(Duration.ofSeconds(1));
6060
client = HttpClient.Factory.createDefault().createClient(config);
6161
}
6262

@@ -82,8 +82,8 @@ void canReturnAppropriateFallbackResponse() {
8282
throw new TimeoutException();
8383
});
8484

85-
Assertions.assertEquals(
86-
HTTP_GATEWAY_TIMEOUT, handler1.execute(new HttpRequest(GET, "/")).getStatus());
85+
Assertions.assertThrows(
86+
TimeoutException.class, () -> handler1.execute(new HttpRequest(GET, "/")));
8787

8888
HttpHandler handler2 =
8989
new RetryRequest()
@@ -96,12 +96,11 @@ void canReturnAppropriateFallbackResponse() {
9696
@Test
9797
void canReturnAppropriateFallbackResponseWithMultipleThreads()
9898
throws InterruptedException, ExecutionException {
99-
HttpHandler handler1 =
100-
new RetryRequest()
101-
.andFinally(
102-
(HttpRequest request) -> {
103-
throw new TimeoutException();
104-
});
99+
AppServer server = new NettyAppServer(req -> new HttpResponse());
100+
101+
URI uri = URI.create(server.whereIs("/"));
102+
HttpRequest connectionTimeoutRequest =
103+
new HttpRequest(GET, String.format(REQUEST_PATH, uri.getHost(), uri.getPort()));
105104

106105
HttpHandler handler2 =
107106
new RetryRequest()
@@ -110,12 +109,12 @@ void canReturnAppropriateFallbackResponseWithMultipleThreads()
110109
ExecutorService executorService = Executors.newFixedThreadPool(2);
111110
List<Callable<HttpResponse>> tasks = new ArrayList<>();
112111

113-
tasks.add(() -> handler1.execute(new HttpRequest(GET, "/")));
112+
tasks.add(() -> client.execute(connectionTimeoutRequest));
114113
tasks.add(() -> handler2.execute(new HttpRequest(GET, "/")));
115114

116115
List<Future<HttpResponse>> results = executorService.invokeAll(tasks);
117116

118-
Assertions.assertEquals(HTTP_GATEWAY_TIMEOUT, results.get(0).get().getStatus());
117+
Assertions.assertEquals(HTTP_CLIENT_TIMEOUT, results.get(0).get().getStatus());
119118

120119
Assertions.assertEquals(HTTP_UNAVAILABLE, results.get(1).get().getStatus());
121120
}
@@ -265,70 +264,6 @@ void shouldGetTheErrorResponseOnServerUnavailableError() {
265264
server.stop();
266265
}
267266

268-
@Test
269-
void shouldBeAbleToRetryARequestOnTimeout() {
270-
AtomicInteger count = new AtomicInteger(0);
271-
AppServer server =
272-
new NettyAppServer(
273-
req -> {
274-
count.incrementAndGet();
275-
if (count.get() <= 3) {
276-
try {
277-
Thread.sleep(2000);
278-
} catch (InterruptedException e) {
279-
e.printStackTrace();
280-
}
281-
}
282-
return new HttpResponse();
283-
});
284-
server.start();
285-
286-
URI uri = URI.create(server.whereIs("/"));
287-
HttpRequest request =
288-
new HttpRequest(GET, String.format(REQUEST_PATH, uri.getHost(), uri.getPort()));
289-
290-
HttpResponse response = client.execute(request);
291-
assertThat(response).extracting(HttpResponse::getStatus).isEqualTo(HTTP_OK);
292-
assertThat(count.get()).isEqualTo(4);
293-
294-
server.stop();
295-
}
296-
297-
@Test
298-
void shouldBeAbleToGetErrorResponseOnRequestTimeout() {
299-
AtomicInteger count = new AtomicInteger(0);
300-
AppServer server =
301-
new NettyAppServer(
302-
req -> {
303-
count.incrementAndGet();
304-
throw new TimeoutException();
305-
});
306-
server.start();
307-
308-
URI uri = URI.create(server.whereIs("/"));
309-
HttpRequest request =
310-
new HttpRequest(GET, String.format(REQUEST_PATH, uri.getHost(), uri.getPort()));
311-
312-
HttpResponse response = client.execute(request);
313-
314-
// The NettyAppServer passes the request through ErrorFilter.
315-
// This maps the timeout exception to HTTP response code 500 and HTTP response body containing
316-
// "timeout".
317-
// RetryRequest retries if it gets a TimeoutException only.
318-
// Parsing and inspecting the response body each time if HTTP response code 500 is not
319-
// efficient.
320-
// A potential solution can be updating the ErrorCodec to reflect the appropriate HTTP code
321-
// (this is a breaking change).
322-
// RetryRequest can then inspect just the HTTP response status code and retry.
323-
324-
assertThat(response).extracting(HttpResponse::getStatus).isEqualTo(HTTP_INTERNAL_ERROR);
325-
326-
// This should ideally be more than the number of retries configured i.e. greater than 3
327-
assertThat(count.get()).isEqualTo(1);
328-
329-
server.stop();
330-
}
331-
332267
@Test
333268
void shouldBeAbleToRetryARequestOnConnectionFailure() {
334269
AppServer server = new NettyAppServer(req -> new HttpResponse());

0 commit comments

Comments
 (0)