Skip to content

Commit f3ca986

Browse files
committed
Re-use HttpAsyncClient
1 parent 6d10db7 commit f3ca986

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

src/main/java/me/itzg/helpers/http/FetchBuilderBase.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
import me.itzg.helpers.errors.GenericException;
3030
import me.itzg.helpers.http.SharedFetch.Options;
3131
import me.itzg.helpers.json.ObjectMappers;
32+
import org.apache.hc.client5.http.async.HttpAsyncClient;
3233
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
34+
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
3335
import org.slf4j.Logger;
3436
import reactor.core.publisher.Mono;
3537
import reactor.netty.ByteBufMono;
@@ -177,6 +179,10 @@ protected interface ReactiveClientUser<R> {
177179
R use(HttpClient client);
178180
}
179181

182+
protected interface HcAsyncClientUser<R> {
183+
R use(HttpAsyncClient client);
184+
}
185+
180186
protected <R> R useReactiveClient(ReactiveClientUser<R> user) {
181187
if (state.sharedFetch != null) {
182188
return user.use(state.sharedFetch.getReactiveClient());
@@ -188,6 +194,10 @@ protected <R> R useReactiveClient(ReactiveClientUser<R> user) {
188194
}
189195
}
190196

197+
protected CloseableHttpAsyncClient getHcAsyncClient() {
198+
return state.sharedFetch.getHcAsyncClient();
199+
}
200+
191201
protected static BiConsumer<? super HttpClientRequest, ? super Connection> debugLogRequest(
192202
Logger log, String operation
193203
) {

src/main/java/me/itzg/helpers/http/OutputToDirectoryFetchBuilder.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import org.apache.hc.client5.http.async.methods.AbstractBinResponseConsumer;
1919
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
2020
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
21-
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
22-
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
2321
import org.apache.hc.core5.http.ContentType;
2422
import org.apache.hc.core5.http.HttpException;
2523
import org.apache.hc.core5.http.HttpResponse;
@@ -36,7 +34,6 @@
3634
public class OutputToDirectoryFetchBuilder extends FetchBuilderBase<OutputToDirectoryFetchBuilder> {
3735

3836
private final Path outputDirectory;
39-
private final CloseableHttpAsyncClient hcHttpClient;
4037

4138
@Setter
4239
private boolean skipExisting;
@@ -56,9 +53,6 @@ protected OutputToDirectoryFetchBuilder(State state, Path outputDirectory) {
5653
throw new IllegalArgumentException(outputDirectory + " is not a directory or does not exist");
5754
}
5855
this.outputDirectory = outputDirectory;
59-
60-
hcHttpClient = HttpAsyncClients.createDefault();
61-
hcHttpClient.start();
6256
}
6357

6458
@SuppressWarnings("unused")
@@ -225,7 +219,7 @@ else if (skipUpToDate) {
225219
.map(instant -> reqBuilder.setHeader("If-Modified-Since", httpDateTimeFormatter.format(instant)))
226220
.then(
227221
Mono.<Path>create(sink -> {
228-
hcHttpClient.execute(
222+
getHcAsyncClient().execute(
229223
SimpleRequestProducer.create(reqBuilder.build()),
230224
new ResponseToFileConsumer(outputFile),
231225
new MonoSinkFutureCallbackAdapter<>(sink)

src/main/java/me/itzg/helpers/http/SharedFetch.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package me.itzg.helpers.http;
22

33
import io.netty.handler.codec.http.HttpHeaderNames;
4+
import java.io.IOException;
45
import java.net.URI;
56
import java.time.Duration;
67
import java.util.HashMap;
@@ -12,6 +13,8 @@
1213
import lombok.extern.slf4j.Slf4j;
1314
import me.itzg.helpers.McImageHelper;
1415
import me.itzg.helpers.errors.GenericException;
16+
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
17+
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
1518
import reactor.netty.http.Http11SslContextSpec;
1619
import reactor.netty.http.client.HttpClient;
1720
import reactor.netty.resources.ConnectionProvider;
@@ -32,6 +35,8 @@ public class SharedFetch implements AutoCloseable {
3235
final LatchingUrisInterceptor latchingUrisInterceptor = new LatchingUrisInterceptor();
3336

3437
private final HttpClient reactiveClient;
38+
private final CloseableHttpAsyncClient hcAsyncClient;
39+
private boolean hcAsyncClientStarted = false;
3540

3641
public SharedFetch(String forCommand, Options options) {
3742
final String userAgent = String.format("%s/%s/%s (cmd=%s)",
@@ -74,6 +79,16 @@ public SharedFetch(String forCommand, Options options) {
7479
);
7580

7681
headers.put("x-fetch-session", fetchSessionId);
82+
83+
hcAsyncClient = HttpAsyncClients.createSystem();
84+
}
85+
86+
public synchronized CloseableHttpAsyncClient getHcAsyncClient() {
87+
if (!hcAsyncClientStarted) {
88+
hcAsyncClient.start();
89+
hcAsyncClientStarted = true;
90+
}
91+
return hcAsyncClient;
7792
}
7893

7994
public FetchBuilderBase<?> fetch(URI uri) {
@@ -88,6 +103,11 @@ public SharedFetch addHeader(String name, String value) {
88103

89104
@Override
90105
public void close() {
106+
try {
107+
hcAsyncClient.close();
108+
} catch (IOException e) {
109+
log.warn("Failed to close async client for shared fetch", e);
110+
}
91111
}
92112

93113
@Builder

0 commit comments

Comments
 (0)