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
	
	 Chris Eager
						Chris Eager