Skip to content

Commit d1000c3

Browse files
Nima WebClient configuration for timeouts and keepAlive (helidon-io#6971)
* Nima WebClient Shortcuts for timeouts * WebClient config for keepAlive * Implement build() in WebClient.Builder and introduce an abstract doBuild method. This allows WebClient.Builder to run pre-build code to set the channel options from the default builder. Slight re-org of WebClient.Builder: - move all package private methods at the bottom - add javadoc to protected methods Update javadoc related to the default socket options builder. --------- Signed-off-by: aserkes <andrii.serkes@oracle.com> Co-authored-by: Romain Grecourt <romain.grecourt@oracle.com>
1 parent c181cca commit d1000c3

4 files changed

Lines changed: 97 additions & 19 deletions

File tree

nima/http2/webclient/src/main/java/io/helidon/nima/http2/webclient/Http2Client.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public Http2ClientBuilder prefetch(int prefetch) {
129129
}
130130

131131
@Override
132-
public Http2Client build() {
132+
public Http2Client doBuild() {
133133
return new Http2ClientImpl(this);
134134
}
135135

nima/webclient/webclient/src/main/java/io/helidon/nima/webclient/WebClient.java

Lines changed: 93 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package io.helidon.nima.webclient;
1818

1919
import java.net.URI;
20+
import java.time.Duration;
2021
import java.util.List;
2122
import java.util.Objects;
23+
import java.util.function.Consumer;
2224
import java.util.function.Function;
2325
import java.util.function.Supplier;
2426

@@ -69,6 +71,7 @@ abstract class Builder<B extends Builder<B, C>, C extends WebClient> implements
6971
private URI baseUri;
7072
private Tls tls;
7173
private SocketOptions channelOptions;
74+
private final SocketOptions.Builder channelOptionsBuilder = SocketOptions.builder();
7275
private DnsResolver dnsResolver;
7376
private DnsAddressLookup dnsAddressLookup;
7477
private boolean followRedirect;
@@ -82,6 +85,21 @@ abstract class Builder<B extends Builder<B, C>, C extends WebClient> implements
8285
protected Builder() {
8386
}
8487

88+
/**
89+
* Actual {@link #build()} implementation for {@link WebClient} subclasses.
90+
*
91+
* @return new client
92+
*/
93+
protected abstract C doBuild();
94+
95+
@Override
96+
public C build() {
97+
if (channelOptions == null) {
98+
channelOptions = channelOptionsBuilder.build();
99+
}
100+
return doBuild();
101+
}
102+
85103
/**
86104
* Base uri used by the client in all requests.
87105
*
@@ -131,6 +149,14 @@ public B tls(Supplier<Tls> tls) {
131149

132150
/**
133151
* Socket options for connections opened by this client.
152+
* Note that using this method will trump the default {@link SocketOptions.Builder}.
153+
* Thus, all methods that operate on the default {@link SocketOptions.Builder} are ineffective:
154+
* <ul>
155+
* <li>{@link #channelOptions(Consumer)} </li>
156+
* <li>{@link #readTimeout(Duration)}</li>
157+
* <li>{@link #connectTimeout(Duration)} (Duration)}</li>
158+
* <li>{@link #keepAlive(boolean)}</li>
159+
* </ul>
134160
*
135161
* @param channelOptions options
136162
* @return updated builder
@@ -140,6 +166,17 @@ public B channelOptions(SocketOptions channelOptions) {
140166
return identity();
141167
}
142168

169+
/**
170+
* Configure the socket options for connections opened by this client.
171+
*
172+
* @param consumer {@link SocketOptions.Builder} consumer
173+
* @return updated builder
174+
*/
175+
public B channelOptions(Consumer<SocketOptions.Builder> consumer) {
176+
consumer.accept(channelOptionsBuilder);
177+
return identity();
178+
}
179+
143180
/**
144181
* DNS resolver to be used by this client.
145182
*
@@ -185,6 +222,46 @@ public B maxRedirects(int maxRedirect) {
185222
return identity();
186223
}
187224

225+
/**
226+
* Connect timeout.
227+
* This method operates on the default socket options builder and provides a shortcut for
228+
* {@link SocketOptions.Builder#connectTimeout(Duration)}.
229+
*
230+
* @param connectTimeout connect timeout
231+
* @return updated builder
232+
*/
233+
public B connectTimeout(Duration connectTimeout) {
234+
channelOptionsBuilder.connectTimeout(connectTimeout);
235+
return identity();
236+
}
237+
238+
/**
239+
* Sets the socket read timeout.
240+
* This method operates on the default socket options builder and provides a shortcut for
241+
* {@link SocketOptions.Builder#readTimeout(Duration)}.
242+
*
243+
* @param readTimeout read timeout
244+
* @return updated builder
245+
*/
246+
public B readTimeout(Duration readTimeout) {
247+
channelOptionsBuilder.readTimeout(readTimeout);
248+
return identity();
249+
}
250+
251+
/**
252+
* Configure socket keep alive.
253+
* This method operates on the default socket options builder and provides a shortcut for
254+
* {@link SocketOptions.Builder#socketKeepAlive(boolean)}.
255+
*
256+
* @param keepAlive keep alive
257+
* @return updated builder
258+
* @see java.net.StandardSocketOptions#SO_KEEPALIVE
259+
*/
260+
public B keepAlive(boolean keepAlive) {
261+
channelOptionsBuilder.socketKeepAlive(keepAlive);
262+
return identity();
263+
}
264+
188265
/**
189266
* Configure a custom header to be sent. Some headers cannot be modified.
190267
*
@@ -200,7 +277,7 @@ public B header(Http.HeaderValue header) {
200277
/**
201278
* Set header with multiple values. Some headers cannot be modified.
202279
*
203-
* @param name header name
280+
* @param name header name
204281
* @param values header values
205282
* @return updated builder instance
206283
*/
@@ -249,24 +326,32 @@ public B mediaTypeParserMode(ParserMode mode) {
249326
*
250327
* @return socket options
251328
*/
252-
SocketOptions channelOptions() {
329+
protected SocketOptions channelOptions() {
253330
return channelOptions;
254331
}
255332

256333
/**
257-
* Configured TLS.
334+
* Default headers to be used in every request.
258335
*
259-
* @return TLS if configured, null otherwise
336+
* @return default headers
260337
*/
261-
Tls tls() {
262-
return tls;
338+
protected WritableHeaders<?> defaultHeaders() {
339+
return defaultHeaders;
263340
}
264341

265342
/**
266-
* Base request uri.
343+
* Media type parsing mode for HTTP {@code Content-Type} header.
267344
*
268-
* @return client request base uri
345+
* @return media type parsing mode
269346
*/
347+
protected ParserMode mediaTypeParserMode() {
348+
return this.mediaTypeParserMode;
349+
}
350+
351+
Tls tls() {
352+
return tls;
353+
}
354+
270355
URI baseUri() {
271356
return baseUri;
272357
}
@@ -287,13 +372,5 @@ int maxRedirect() {
287372
return maxRedirect;
288373
}
289374

290-
protected WritableHeaders<?> defaultHeaders() {
291-
return defaultHeaders;
292-
}
293-
294-
protected ParserMode mediaTypeParserMode() {
295-
return this.mediaTypeParserMode;
296-
}
297-
298375
}
299376
}

nima/webclient/webclient/src/main/java/io/helidon/nima/webclient/http1/Http1Client.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ private Http1ClientBuilder() {
8181
}
8282

8383
@Override
84-
public Http1Client build() {
84+
public Http1Client doBuild() {
8585
configBuilder.defaultHeaders(defaultHeaders());
8686
if (mediaContextBuilder != null) {
8787
configBuilder.mediaContext(mediaContextBuilder.fallback(configBuilder.mediaContext()).build());
8888
}
89+
configBuilder.socketOptions(super.channelOptions());
8990
return new Http1ClientImpl(configBuilder.build());
9091
}
9192

nima/websocket/client/src/main/java/io/helidon/nima/websocket/client/WsClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private Builder() {
8282
}
8383

8484
@Override
85-
public WsClient build() {
85+
public WsClient doBuild() {
8686
// these headers cannot be modified by user
8787
header(HEADER_UPGRADE_WS);
8888
header(HEADER_WS_VERSION);

0 commit comments

Comments
 (0)