diff --git a/CHANGELOG.md b/CHANGELOG.md index ae045fc560a..1729d91d21f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Fix #4793: (java-generator) Fix broken POJO generation when two schema properties collide into a single field name * Fix #4963: Openshift Client return 403 when use websocket * Fix #4985: triggering the immediate cleanup of the okhttp idle task +* Fix #4988: Ensuring that previous requests are closed before retry * fix #5002: Jetty response completion accounts for header processing * Fix #5009: addressing issue with serialization of wrapped polymophic types diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java index 917e91e92f0..da24bcb55e5 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/http/StandardHttpClient.java @@ -145,6 +145,7 @@ protected void retryWithExponentialBackoff(CompletableFuture result, LOG.debug("HTTP operation on url: {} should be retried as the response code was {}, retrying after {} millis", uri, code, retryInterval); retry = true; + cancel.accept(response); } } else if (throwable instanceof IOException) { LOG.debug(String.format("HTTP operation on url: %s should be retried after %d millis because of IOException", diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java index 5e308c28bac..81ddbaccc5f 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/http/StandardHttpClientTest.java @@ -143,7 +143,8 @@ void testHttpRetryWithLessFailuresThanRetries() throws Exception { .withRequestRetryBackoffInterval(50).build()) .build(); - final HttpResponse error = new TestHttpResponse().withCode(500); + final HttpResponse error = new TestHttpResponse().withBody(Mockito.mock(AsyncBody.class)) + .withCode(500); client.getRespFutures().add(CompletableFuture.completedFuture(error)); client.getRespFutures().add(CompletableFuture.completedFuture(error)); client.getRespFutures().add(CompletableFuture.completedFuture(error)); @@ -155,7 +156,7 @@ void testHttpRetryWithLessFailuresThanRetries() throws Exception { }); // should ultimately succeed with the final 200 - assertEquals(200, consumeFuture.get().code()); + assertEquals(200, consumeFuture.get(2, TimeUnit.MINUTES).code()); // only 4 requests issued assertEquals(4, client.getRespFutures().size()); @@ -179,9 +180,35 @@ void testWebSocketWithLessFailuresThanRetries() throws Exception { client.getWsFutures().add(client.getWsFutures().get(0)); client.getWsFutures().add(CompletableFuture.completedFuture((new WebSocketResponse(ws, null)))); - future.get(); + future.get(2, TimeUnit.MINUTES); assertEquals(3, client.getWsFutures().size()); } + @Test + void testClosePreviousBeforeRetry() throws Exception { + client = client.newBuilder().tag(new RequestConfigBuilder() + .withRequestRetryBackoffLimit(1) + .withRequestRetryBackoffInterval(50).build()) + .build(); + + final HttpResponse error = new TestHttpResponse().withBody(Mockito.mock(AsyncBody.class)) + .withCode(503); + client.getRespFutures().add(CompletableFuture.completedFuture(error)); + client.getRespFutures().add(CompletableFuture.completedFuture(new TestHttpResponse().withCode(200))); + + CompletableFuture> consumeFuture = client.consumeBytes( + client.newHttpRequestBuilder().uri("http://localhost").build(), + (value, asyncBody) -> { + }); + + Mockito.verify(error.body()).cancel(); + + // should ultimately succeed with the final 200 + assertEquals(200, consumeFuture.get(2, TimeUnit.MINUTES).code()); + + // only 2 requests issued + assertEquals(2, client.getRespFutures().size()); + } + }