Multiplex GCM messages across 10 HttpClient instances

The underlying HttpClient implementation will not create a new
connection when the max sessions for an HTTP/2 connection have
been reached.
This commit is contained in:
Moxie Marlinspike 2019-06-10 12:37:53 -07:00
parent d6b470ffbe
commit b4f528039f
1 changed files with 15 additions and 6 deletions

View File

@ -27,6 +27,7 @@ import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse.BodyHandlers;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@ -48,13 +49,15 @@ public class Sender {
private static final String PRODUCTION_URL = "https://fcm.googleapis.com/fcm/send";
private final HttpClient client;
private final String authorizationHeader;
private final URI uri;
private final Retry retry;
private final ObjectMapper mapper;
private final ScheduledExecutorService executorService;
private final HttpClient[] clients = new HttpClient[10];
private final SecureRandom random = new SecureRandom();
/**
* Construct a Sender instance.
*
@ -86,10 +89,12 @@ public class Sender {
.retryOnException(this::isRetryableException)
.build());
this.client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
for (int i=0;i<clients.length;i++) {
this.clients[i] = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
}
}
private boolean isRetryableException(Throwable throwable) {
@ -119,7 +124,7 @@ public class Sender {
.build();
return retry.executeCompletionStage(executorService,
() -> client.sendAsync(request, BodyHandlers.ofByteArray())
() -> getClient().sendAsync(request, BodyHandlers.ofByteArray())
.thenApply(response -> {
switch (response.statusCode()) {
case 400: throw new CompletionException(new InvalidRequestException());
@ -155,4 +160,8 @@ public class Sender {
return retry;
}
private HttpClient getClient() {
return clients[random.nextInt(clients.length)];
}
}