Skip to content

Commit a16abbf

Browse files
committed
Async client can now be used internally by the Fluent facade
1 parent a1243ed commit a16abbf

File tree

2 files changed

+89
-16
lines changed

2 files changed

+89
-16
lines changed

httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Executor.java

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import java.io.IOException;
3030
import java.net.URISyntaxException;
31+
import java.util.concurrent.locks.ReentrantLock;
3132

3233
import org.apache.hc.client5.http.auth.AuthCache;
3334
import org.apache.hc.client5.http.auth.AuthScope;
@@ -36,15 +37,21 @@
3637
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
3738
import org.apache.hc.client5.http.config.ConnectionConfig;
3839
import org.apache.hc.client5.http.cookie.CookieStore;
40+
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
41+
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
3942
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
4043
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
4144
import org.apache.hc.client5.http.impl.auth.BasicScheme;
4245
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
4346
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
47+
import org.apache.hc.client5.http.impl.compat.ClassicToAsyncAdaptor;
4448
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
49+
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
4550
import org.apache.hc.client5.http.protocol.HttpClientContext;
51+
import org.apache.hc.core5.annotation.Experimental;
4652
import org.apache.hc.core5.http.HttpHost;
4753
import org.apache.hc.core5.util.TimeValue;
54+
import org.apache.hc.core5.util.Timeout;
4855

4956
/**
5057
* Executor for {@link Request}s.
@@ -56,30 +63,82 @@
5663
*/
5764
public class Executor {
5865

59-
final static CloseableHttpClient CLIENT;
66+
private static final ReentrantLock LOCK = new ReentrantLock();
67+
private static volatile CloseableHttpClient CLIENT;
68+
private static volatile CloseableHttpClient ASYNC_CLIENT;
6069

61-
static {
62-
CLIENT = HttpClientBuilder.create()
63-
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
70+
static CloseableHttpClient GET_CLASSIC_CLIENT() {
71+
final CloseableHttpClient client = CLIENT;
72+
if (client != null) {
73+
return client;
74+
}
75+
LOCK.lock();
76+
try {
77+
if (CLIENT == null) {
78+
CLIENT = HttpClientBuilder.create()
79+
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
80+
.useSystemProperties()
81+
.setMaxConnPerRoute(100)
82+
.setMaxConnTotal(200)
83+
.setDefaultConnectionConfig(ConnectionConfig.custom()
84+
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
85+
.build())
86+
.build())
6487
.useSystemProperties()
65-
.setMaxConnPerRoute(100)
66-
.setMaxConnTotal(200)
67-
.setDefaultConnectionConfig(ConnectionConfig.custom()
68-
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
88+
.evictExpiredConnections()
89+
.evictIdleConnections(TimeValue.ofMinutes(1))
90+
.build();
91+
}
92+
return CLIENT;
93+
} finally {
94+
LOCK.unlock();
95+
}
96+
}
97+
98+
static CloseableHttpClient GET_ASYNC_CLIENT() {
99+
final CloseableHttpClient client = ASYNC_CLIENT;
100+
if (client != null) {
101+
return client;
102+
}
103+
LOCK.lock();
104+
try {
105+
if (ASYNC_CLIENT == null) {
106+
ASYNC_CLIENT = new ClassicToAsyncAdaptor(HttpAsyncClientBuilder.create()
107+
.setConnectionManager(PoolingAsyncClientConnectionManagerBuilder.create()
108+
.useSystemProperties()
109+
.setMaxConnPerRoute(100)
110+
.setMaxConnTotal(200)
111+
.setMessageMultiplexing(true)
112+
.setDefaultConnectionConfig(ConnectionConfig.custom()
113+
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
114+
.build())
69115
.build())
70-
.build())
71-
.useSystemProperties()
72-
.evictExpiredConnections()
73-
.evictIdleConnections(TimeValue.ofMinutes(1))
74-
.build();
116+
.useSystemProperties()
117+
.evictExpiredConnections()
118+
.evictIdleConnections(TimeValue.ofMinutes(1))
119+
.build(), Timeout.ofMinutes(5));
120+
}
121+
return ASYNC_CLIENT;
122+
} finally {
123+
LOCK.unlock();
124+
}
75125
}
76126

77127
public static Executor newInstance() {
78-
return new Executor(CLIENT);
128+
return new Executor(GET_CLASSIC_CLIENT());
79129
}
80130

81131
public static Executor newInstance(final CloseableHttpClient httpclient) {
82-
return new Executor(httpclient != null ? httpclient : CLIENT);
132+
return new Executor(httpclient != null ? httpclient : GET_CLASSIC_CLIENT());
133+
}
134+
135+
/**
136+
* This feature is considered experimental and may be discontinued in the future.
137+
* @since 5.5
138+
*/
139+
@Experimental
140+
public static Executor newInstance(final CloseableHttpAsyncClient httpclient) {
141+
return new Executor(httpclient != null ? new ClassicToAsyncAdaptor(httpclient, Timeout.ofMinutes(5)) : GET_ASYNC_CLIENT());
83142
}
84143

85144
private final CloseableHttpClient httpclient;

httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
4848
import org.apache.hc.client5.http.protocol.HttpClientContext;
4949
import org.apache.hc.client5.http.utils.DateUtils;
50+
import org.apache.hc.core5.annotation.Experimental;
5051
import org.apache.hc.core5.http.ClassicHttpRequest;
5152
import org.apache.hc.core5.http.ClassicHttpResponse;
5253
import org.apache.hc.core5.http.ContentType;
@@ -202,7 +203,20 @@ ClassicHttpResponse internalExecute(
202203
}
203204

204205
public Response execute() throws IOException {
205-
return execute(Executor.CLIENT);
206+
return execute(Executor.GET_CLASSIC_CLIENT());
207+
}
208+
209+
/**
210+
* Execute the request using an HTTP/2 capable engine. The exact protocol version
211+
* will still have to be negotiated by individual connections.
212+
* <p>
213+
* This feature is considered experimental and may be discontinued in the future.
214+
*
215+
* @since 5.5
216+
*/
217+
@Experimental
218+
public Response executeHttp2() throws IOException {
219+
return execute(Executor.GET_ASYNC_CLIENT());
206220
}
207221

208222
public Response execute(final CloseableHttpClient client) throws IOException {

0 commit comments

Comments
 (0)