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 { | ||||
| 
 | ||||
|   private final HttpClient httpClient; | ||||
|   private final Duration defaultRequestTimeout; | ||||
|   private final ScheduledExecutorService retryExecutor; | ||||
|   private final Retry retry; | ||||
|   private final CircuitBreaker breaker; | ||||
|  | @ -40,9 +41,12 @@ public class FaultTolerantHttpClient { | |||
|   } | ||||
| 
 | ||||
|   private FaultTolerantHttpClient(String name, HttpClient httpClient, ScheduledExecutorService retryExecutor, | ||||
|       RetryConfiguration retryConfiguration, CircuitBreakerConfiguration circuitBreakerConfiguration) { | ||||
|       Duration defaultRequestTimeout, RetryConfiguration retryConfiguration, | ||||
|       CircuitBreakerConfiguration circuitBreakerConfiguration) { | ||||
| 
 | ||||
|     this.httpClient = httpClient; | ||||
|     this.retryExecutor = retryExecutor; | ||||
|     this.defaultRequestTimeout = defaultRequestTimeout; | ||||
|     this.breaker = CircuitBreaker.of(name + "-breaker", circuitBreakerConfiguration.toCircuitBreakerConfig()); | ||||
| 
 | ||||
|     CircuitBreakerUtil.registerMetrics(breaker, FaultTolerantHttpClient.class); | ||||
|  | @ -61,6 +65,12 @@ public class FaultTolerantHttpClient { | |||
|   } | ||||
| 
 | ||||
|   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); | ||||
| 
 | ||||
|     if (retry != null) { | ||||
|  | @ -83,6 +93,7 @@ public class FaultTolerantHttpClient { | |||
|     private HttpClient.Version version = HttpClient.Version.HTTP_2; | ||||
|     private HttpClient.Redirect redirect = HttpClient.Redirect.NEVER; | ||||
|     private Duration connectTimeout = Duration.ofSeconds(10); | ||||
|     private Duration requestTimeout = Duration.ofSeconds(60); | ||||
| 
 | ||||
|     private String name; | ||||
|     private Executor executor; | ||||
|  | @ -120,6 +131,11 @@ public class FaultTolerantHttpClient { | |||
|       return this; | ||||
|     } | ||||
| 
 | ||||
|     public Builder withRequestTimeout(Duration requestTimeout) { | ||||
|       this.requestTimeout = requestTimeout; | ||||
|       return this; | ||||
|     } | ||||
| 
 | ||||
|     public Builder withRetry(RetryConfiguration retryConfiguration) { | ||||
|       this.retryConfiguration = retryConfiguration; | ||||
|       return this; | ||||
|  | @ -164,7 +180,7 @@ public class FaultTolerantHttpClient { | |||
| 
 | ||||
|       builder.sslContext(sslConfigurator.createSSLContext()); | ||||
| 
 | ||||
|       return new FaultTolerantHttpClient(name, builder.build(), retryExecutor, retryConfiguration, | ||||
|       return new FaultTolerantHttpClient(name, builder.build(), retryExecutor, requestTimeout, retryConfiguration, | ||||
|           circuitBreakerConfiguration); | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -19,7 +19,9 @@ import com.braintreegateway.TransactionSearchRequest; | |||
| import com.braintreegateway.exceptions.BraintreeException; | ||||
| import com.braintreegateway.exceptions.NotFoundException; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.Duration; | ||||
| import java.time.Instant; | ||||
| import java.util.Collections; | ||||
| import java.util.Comparator; | ||||
|  | @ -37,7 +39,6 @@ import javax.annotation.Nullable; | |||
| import javax.ws.rs.ClientErrorException; | ||||
| import javax.ws.rs.WebApplicationException; | ||||
| import javax.ws.rs.core.Response; | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; | ||||
|  | @ -74,6 +75,10 @@ public class BraintreeManager implements SubscriptionProcessorManager { | |||
|             .withCircuitBreaker(circuitBreakerConfiguration) | ||||
|             .withExecutor(executor) | ||||
|             .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), | ||||
|         executor); | ||||
|   } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Chris Eager
						Chris Eager