Add default request timeout to FaultTolerantHttpClient
This commit is contained in:
parent
ebbe19ba63
commit
a1e534a515
|
@ -28,6 +28,7 @@ import org.whispersystems.textsecuregcm.util.CircuitBreakerUtil;
|
||||||
public class FaultTolerantHttpClient {
|
public class FaultTolerantHttpClient {
|
||||||
|
|
||||||
private final HttpClient httpClient;
|
private final HttpClient httpClient;
|
||||||
|
private final Duration defaultRequestTimeout;
|
||||||
private final ScheduledExecutorService retryExecutor;
|
private final ScheduledExecutorService retryExecutor;
|
||||||
private final Retry retry;
|
private final Retry retry;
|
||||||
private final CircuitBreaker breaker;
|
private final CircuitBreaker breaker;
|
||||||
|
@ -40,9 +41,12 @@ public class FaultTolerantHttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private FaultTolerantHttpClient(String name, HttpClient httpClient, ScheduledExecutorService retryExecutor,
|
private FaultTolerantHttpClient(String name, HttpClient httpClient, ScheduledExecutorService retryExecutor,
|
||||||
RetryConfiguration retryConfiguration, CircuitBreakerConfiguration circuitBreakerConfiguration) {
|
Duration defaultRequestTimeout, RetryConfiguration retryConfiguration,
|
||||||
|
CircuitBreakerConfiguration circuitBreakerConfiguration) {
|
||||||
|
|
||||||
this.httpClient = httpClient;
|
this.httpClient = httpClient;
|
||||||
this.retryExecutor = retryExecutor;
|
this.retryExecutor = retryExecutor;
|
||||||
|
this.defaultRequestTimeout = defaultRequestTimeout;
|
||||||
this.breaker = CircuitBreaker.of(name + "-breaker", circuitBreakerConfiguration.toCircuitBreakerConfig());
|
this.breaker = CircuitBreaker.of(name + "-breaker", circuitBreakerConfiguration.toCircuitBreakerConfig());
|
||||||
|
|
||||||
CircuitBreakerUtil.registerMetrics(breaker, FaultTolerantHttpClient.class);
|
CircuitBreakerUtil.registerMetrics(breaker, FaultTolerantHttpClient.class);
|
||||||
|
@ -61,6 +65,12 @@ public class FaultTolerantHttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, HttpResponse.BodyHandler<T> bodyHandler) {
|
public <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, HttpResponse.BodyHandler<T> bodyHandler) {
|
||||||
|
if (request.timeout().isEmpty()) {
|
||||||
|
request = HttpRequest.newBuilder(request, (n, v) -> true)
|
||||||
|
.timeout(defaultRequestTimeout)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
Supplier<CompletionStage<HttpResponse<T>>> asyncRequest = sendAsync(httpClient, request, bodyHandler);
|
Supplier<CompletionStage<HttpResponse<T>>> asyncRequest = sendAsync(httpClient, request, bodyHandler);
|
||||||
|
|
||||||
if (retry != null) {
|
if (retry != null) {
|
||||||
|
@ -83,6 +93,7 @@ public class FaultTolerantHttpClient {
|
||||||
private HttpClient.Version version = HttpClient.Version.HTTP_2;
|
private HttpClient.Version version = HttpClient.Version.HTTP_2;
|
||||||
private HttpClient.Redirect redirect = HttpClient.Redirect.NEVER;
|
private HttpClient.Redirect redirect = HttpClient.Redirect.NEVER;
|
||||||
private Duration connectTimeout = Duration.ofSeconds(10);
|
private Duration connectTimeout = Duration.ofSeconds(10);
|
||||||
|
private Duration requestTimeout = Duration.ofSeconds(60);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
|
@ -120,6 +131,11 @@ public class FaultTolerantHttpClient {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder withRequestTimeout(Duration requestTimeout) {
|
||||||
|
this.requestTimeout = requestTimeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder withRetry(RetryConfiguration retryConfiguration) {
|
public Builder withRetry(RetryConfiguration retryConfiguration) {
|
||||||
this.retryConfiguration = retryConfiguration;
|
this.retryConfiguration = retryConfiguration;
|
||||||
return this;
|
return this;
|
||||||
|
@ -164,7 +180,7 @@ public class FaultTolerantHttpClient {
|
||||||
|
|
||||||
builder.sslContext(sslConfigurator.createSSLContext());
|
builder.sslContext(sslConfigurator.createSSLContext());
|
||||||
|
|
||||||
return new FaultTolerantHttpClient(name, builder.build(), retryExecutor, retryConfiguration,
|
return new FaultTolerantHttpClient(name, builder.build(), retryExecutor, requestTimeout, retryConfiguration,
|
||||||
circuitBreakerConfiguration);
|
circuitBreakerConfiguration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ import com.braintreegateway.TransactionSearchRequest;
|
||||||
import com.braintreegateway.exceptions.BraintreeException;
|
import com.braintreegateway.exceptions.BraintreeException;
|
||||||
import com.braintreegateway.exceptions.NotFoundException;
|
import com.braintreegateway.exceptions.NotFoundException;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -37,7 +39,6 @@ import javax.annotation.Nullable;
|
||||||
import javax.ws.rs.ClientErrorException;
|
import javax.ws.rs.ClientErrorException;
|
||||||
import javax.ws.rs.WebApplicationException;
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
||||||
|
@ -74,6 +75,10 @@ public class BraintreeManager implements SubscriptionProcessorManager {
|
||||||
.withCircuitBreaker(circuitBreakerConfiguration)
|
.withCircuitBreaker(circuitBreakerConfiguration)
|
||||||
.withExecutor(executor)
|
.withExecutor(executor)
|
||||||
.withRetryExecutor(retryExecutor)
|
.withRetryExecutor(retryExecutor)
|
||||||
|
// Braintree documents its internal timeout at 60 seconds, and we want to make sure we don’t miss
|
||||||
|
// a response
|
||||||
|
// https://developer.paypal.com/braintree/docs/reference/general/best-practices/java#timeouts
|
||||||
|
.withRequestTimeout(Duration.ofSeconds(70))
|
||||||
.build(), graphqlUri, braintreePublicKey, braintreePrivateKey),
|
.build(), graphqlUri, braintreePublicKey, braintreePrivateKey),
|
||||||
executor);
|
executor);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue