Skip to content

Commit 98c1e6f

Browse files
shawkinsmanusa
authored andcommitted
fix #4911: consolidating several timeouts and refining requestTimeout
1 parent 2d464d4 commit 98c1e6f

File tree

55 files changed

+353
-389
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+353
-389
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#### New Features
1212

1313
#### _**Note**_: Breaking changes
14+
* Fix #4911: Config/RequestConfig.scaleTimeout has been deprectated along with Scalable.scale(count, wait) and DeployableScalableResource.deployLatest(wait). withTimeout may be called before the operation to control the timeout.
15+
* Fix #4911: Config/RequestConfig.websocketTimeout has been removed. Config/RequestConfig.requestTimeout will be used for websocket connection timeouts.
16+
* Fix #4911: HttpClient api/building changes - writeTimeout has been removed, readTimeout has moved to the HttpRequest
1417

1518
### 6.6.2 (2023-05-15)
1619

@@ -20,7 +23,7 @@ Fix #5121: RequestConfig is propagated to derived HttpClient instances
2023
### 6.6.1 (2023-05-11)
2124

2225
#### Bugs
23-
* Fix #5095: moving the enforcement to requestTimeout
26+
* Fix #5095: moving the enforcement of requestTimeout
2427
* Fix #5100: lessened the level of the non-conflicting httpclient implementation warning
2528
* Fix #5102: wait on scale to 0 was not completing
2629
* Fix #5112: Expose put method with InputStream argument in HttpRequest class

httpclient-jdk/src/main/java/io/fabric8/kubernetes/client/jdkhttp/JdkHttpClientImpl.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
/**
6161
* TODO:
6262
* - Mapping to a Reader is always UTF-8
63-
* - determine if write timeout should be implemented
6463
*/
6564
public class JdkHttpClientImpl extends StandardHttpClient<JdkHttpClientImpl, JdkHttpClientFactory, JdkHttpClientBuilderImpl> {
6665

@@ -259,7 +258,7 @@ public CompletableFuture<HttpResponse<AsyncBody>> consumeBytesDirect(StandardHtt
259258
java.net.http.HttpRequest.Builder requestBuilder(StandardHttpRequest request) {
260259
java.net.http.HttpRequest.Builder requestBuilder = java.net.http.HttpRequest.newBuilder();
261260

262-
Duration readTimeout = this.builder.getReadTimeout();
261+
Duration readTimeout = request.getReadTimeout();
263262
if (readTimeout != null && !java.time.Duration.ZERO.equals(readTimeout)) {
264263
requestBuilder.timeout(readTimeout);
265264
}
@@ -306,15 +305,13 @@ public long contentLength() {
306305
@Override
307306
public CompletableFuture<WebSocketResponse> buildWebSocketDirect(
308307
StandardWebSocketBuilder standardWebSocketBuilder, Listener listener) {
309-
final StandardHttpRequest request = standardWebSocketBuilder.asHttpRequest();
308+
StandardHttpRequest request = standardWebSocketBuilder.asHttpRequest();
310309
java.net.http.WebSocket.Builder newBuilder = this.getHttpClient().newWebSocketBuilder();
311310
request.headers().forEach((k, v) -> v.forEach(s -> newBuilder.header(k, s)));
312311
if (standardWebSocketBuilder.getSubprotocol() != null) {
313312
newBuilder.subprotocols(standardWebSocketBuilder.getSubprotocol());
314313
}
315-
// the Watch logic sets a websocketTimeout as the readTimeout
316-
// TODO: this should probably be made clearer in the docs
317-
Duration readTimeout = this.builder.getReadTimeout();
314+
Duration readTimeout = request.getReadTimeout();
318315
if (readTimeout != null && !java.time.Duration.ZERO.equals(readTimeout)) {
319316
newBuilder.connectTimeout(readTimeout);
320317
}

httpclient-jdk/src/test/java/io/fabric8/kubernetes/client/jdkhttp/JdkHttpClientBuilderTest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ void testZeroTimeouts() {
3030
JdkHttpClientBuilderImpl builder = factory.newBuilder();
3131

3232
// should build and be usable without an issue
33-
try (HttpClient client = builder.readTimeout(0, TimeUnit.MILLISECONDS).connectTimeout(0, TimeUnit.MILLISECONDS)
34-
.writeTimeout(0,
35-
TimeUnit.MILLISECONDS)
36-
.build();) {
33+
try (HttpClient client = builder.connectTimeout(0, TimeUnit.MILLISECONDS).build();) {
3734
assertNotNull(client.newHttpRequestBuilder().uri("http://localhost").build());
3835
}
3936
}

httpclient-jetty/src/main/java/io/fabric8/kubernetes/client/jetty/JettyHttpClient.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import io.fabric8.kubernetes.client.KubernetesClientException;
1919
import io.fabric8.kubernetes.client.http.AsyncBody;
2020
import io.fabric8.kubernetes.client.http.AsyncBody.Consumer;
21-
import io.fabric8.kubernetes.client.http.HttpRequest;
2221
import io.fabric8.kubernetes.client.http.HttpResponse;
2322
import io.fabric8.kubernetes.client.http.StandardHttpClient;
2423
import io.fabric8.kubernetes.client.http.StandardHttpClientBuilder;
@@ -100,7 +99,9 @@ private Request newRequest(StandardHttpRequest originalRequest) {
10099
final var request = requestBuilder.build();
101100

102101
var jettyRequest = jetty.newRequest(request.uri()).method(request.method());
103-
jettyRequest.timeout(builder.getReadTimeout().toMillis() + builder.getWriteTimeout().toMillis(), TimeUnit.MILLISECONDS);
102+
if (originalRequest.getReadTimeout() != null) {
103+
jettyRequest.timeout(originalRequest.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
104+
}
104105
jettyRequest.headers(m -> request.headers().forEach((k, l) -> l.forEach(v -> m.add(k, v))));
105106

106107
final var contentType = Optional.ofNullable(request.getContentType());
@@ -136,14 +137,14 @@ public CompletableFuture<WebSocketResponse> buildWebSocketDirect(StandardWebSock
136137
Listener listener) {
137138
try {
138139
jettyWs.start();
139-
final HttpRequest request = standardWebSocketBuilder.asHttpRequest();
140+
StandardHttpRequest request = standardWebSocketBuilder.asHttpRequest();
140141
final ClientUpgradeRequest cur = new ClientUpgradeRequest();
141142
if (Utils.isNotNullOrEmpty(standardWebSocketBuilder.getSubprotocol())) {
142143
cur.setSubProtocols(standardWebSocketBuilder.getSubprotocol());
143144
}
144145
cur.setHeaders(request.headers());
145-
if (builder.getReadTimeout() != null) {
146-
cur.setTimeout(builder.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
146+
if (request.getReadTimeout() != null) {
147+
cur.setTimeout(request.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
147148
}
148149
// Extra-future required because we can't Map the UpgradeException to a WebSocketHandshakeException easily
149150
final CompletableFuture<WebSocketResponse> future = new CompletableFuture<>();

httpclient-jetty/src/main/java/io/fabric8/kubernetes/client/jetty/JettyHttpClientBuilder.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,6 @@ protected JettyHttpClientBuilder newInstance(JettyHttpClientFactory clientFactor
111111
return new JettyHttpClientBuilder(clientFactory);
112112
}
113113

114-
@Override
115-
public Duration getReadTimeout() {
116-
return Optional.ofNullable(readTimeout).orElse(Duration.ZERO);
117-
}
118-
119-
@Override
120-
public Duration getWriteTimeout() {
121-
return Optional.ofNullable(writeTimeout).orElse(Duration.ZERO);
122-
}
123-
124114
@Override
125115
public Duration getConnectTimeout() {
126116
return Optional.ofNullable(connectTimeout).orElse(Duration.ZERO);

httpclient-jetty/src/test/java/io/fabric8/kubernetes/client/jetty/JettyHttpClientTest.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,12 @@ void newBuilderInstantiatesJettyHttpClientBuilderWithSameSettings() throws Excep
6868
final var originalBuilder = new JettyHttpClientBuilder(null);
6969
originalBuilder
7070
.connectTimeout(1337, TimeUnit.SECONDS)
71-
.readTimeout(1337, TimeUnit.SECONDS)
7271
.tlsVersions(TlsVersion.SSL_3_0)
7372
.followAllRedirects();
7473
try (var firstClient = new JettyHttpClient(
7574
originalBuilder, httpClient, webSocketClient)) {
7675
// When
77-
final var result = firstClient.newBuilder()
78-
.readTimeout(313373, TimeUnit.SECONDS);
76+
final var result = firstClient.newBuilder();
7977
// Then
8078
assertThat(result)
8179
.isNotNull()
@@ -90,11 +88,11 @@ void newBuilderInstantiatesJettyHttpClientBuilderWithSameSettings() throws Excep
9088
.isEqualTo(method.invoke(originalBuilder))
9189
.isEqualTo(entry.getValue());
9290
}
93-
var readTimeout = StandardHttpClientBuilder.class.getDeclaredField("readTimeout");
94-
readTimeout.setAccessible(true);
95-
assertThat(readTimeout.get(result)).isEqualTo(Duration.ofSeconds(313373));
96-
assertThat(readTimeout.get(originalBuilder)).isEqualTo(Duration.ofSeconds(1337));
97-
readTimeout.setAccessible(false);
91+
var connectTimeout = StandardHttpClientBuilder.class.getDeclaredField("connectTimeout");
92+
connectTimeout.setAccessible(true);
93+
assertThat(connectTimeout.get(result)).isEqualTo(Duration.ofSeconds(1337));
94+
assertThat(connectTimeout.get(originalBuilder)).isEqualTo(Duration.ofSeconds(1337));
95+
connectTimeout.setAccessible(false);
9896
}
9997
}
10098

httpclient-okhttp/src/main/java/io/fabric8/kubernetes/client/okhttp/OkHttpClientBuilderImpl.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,9 @@ public OkHttpClientImpl initialBuild(okhttp3.OkHttpClient.Builder builder) {
9191
}
9292

9393
private OkHttpClientImpl derivedBuild(okhttp3.OkHttpClient.Builder builder) {
94-
if (readTimeout != null) {
95-
builder.readTimeout(this.readTimeout);
96-
}
97-
if (writeTimeout != null) {
98-
builder.writeTimeout(this.writeTimeout);
99-
}
10094
if (authenticatorNone) {
10195
builder.authenticator(Authenticator.NONE);
10296
}
103-
if (forStreaming) {
104-
builder.cache(null);
105-
}
10697
OkHttpClient client = builder.build();
10798

10899
return new OkHttpClientImpl(client, this);

httpclient-okhttp/src/main/java/io/fabric8/kubernetes/client/okhttp/OkHttpClientImpl.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,24 @@ public void close() {
291291
}
292292
}
293293

294-
private CompletableFuture<HttpResponse<AsyncBody>> sendAsync(HttpRequest request,
294+
private CompletableFuture<HttpResponse<AsyncBody>> sendAsync(StandardHttpRequest request,
295295
Function<BufferedSource, AsyncBody> handler) {
296296
CompletableFuture<HttpResponse<AsyncBody>> future = new CompletableFuture<>();
297-
Call call = httpClient.newCall(requestBuilder((StandardHttpRequest) request).build());
297+
298+
okhttp3.OkHttpClient.Builder clientBuilder = null;
299+
if (request.getReadTimeout() != null) {
300+
clientBuilder = httpClient.newBuilder();
301+
clientBuilder.readTimeout(request.getReadTimeout());
302+
}
303+
if (request.isForStreaming()) {
304+
if (clientBuilder == null) {
305+
clientBuilder = httpClient.newBuilder();
306+
}
307+
clientBuilder.cache(null);
308+
}
309+
310+
Call call = Optional.ofNullable(clientBuilder).map(okhttp3.OkHttpClient.Builder::build).orElse(httpClient)
311+
.newCall(requestBuilder(request).build());
298312
try {
299313
call.enqueue(new Callback() {
300314

httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClient.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,16 @@ public CompletableFuture<WebSocketResponse> buildWebSocketDirect(StandardWebSock
6363
WebSocket.Listener listener) {
6464
WebSocketConnectOptions options = new WebSocketConnectOptions();
6565

66-
if (builder.getReadTimeout() != null) {
67-
options.setTimeout(builder.getReadTimeout().toMillis());
68-
}
69-
7066
if (standardWebSocketBuilder.getSubprotocol() != null) {
7167
options.setSubProtocols(Collections.singletonList(standardWebSocketBuilder.getSubprotocol()));
7268
}
7369

7470
final StandardHttpRequest request = standardWebSocketBuilder.asHttpRequest();
7571

72+
if (request.getReadTimeout() != null) {
73+
options.setTimeout(request.getReadTimeout().toMillis());
74+
}
75+
7676
request.headers().entrySet().stream()
7777
.forEach(e -> e.getValue().stream().forEach(v -> options.addHeader(e.getKey(), v)));
7878
options.setAbsoluteURI(request.uri().toString());
@@ -107,6 +107,10 @@ public CompletableFuture<HttpResponse<AsyncBody>> consumeBytesDirect(StandardHtt
107107
options.setAbsoluteURI(request.uri().toString());
108108
options.setMethod(HttpMethod.valueOf(request.method()));
109109

110+
if (request.getReadTimeout() != null) {
111+
options.setTimeout(request.getReadTimeout().toMillis());
112+
}
113+
110114
// Proxy authorization is handled manually since the proxyAuthorization value is the actual header
111115
if (proxyAuthorization != null) {
112116
options.putHeader(HttpHeaders.PROXY_AUTHORIZATION, proxyAuthorization);

httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClientBuilder.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ public VertxHttpClient<F> build() {
6161
options.setConnectTimeout((int) this.connectTimeout.toMillis());
6262
}
6363

64-
if (this.writeTimeout != null) {
65-
options.setWriteIdleTimeout((int) this.writeTimeout.getSeconds());
66-
}
67-
6864
if (this.followRedirects) {
6965
options.setFollowRedirects(followRedirects);
7066
}

0 commit comments

Comments
 (0)