Browse Source

[ML] Set Connect Timeout to 5s (#123272)

Reduced connection timeout from infinite to a system configurable
setting that defaults to 5s.

Increased EIS auth token timeout from 30s to 1m.
Pat Whelan 7 months ago
parent
commit
4c3ceae986

+ 5 - 0
docs/changelog/123272.yaml

@@ -0,0 +1,5 @@
+pr: 123272
+summary: Set Connect Timeout to 5s
+area: Machine Learning
+type: bug
+issues: []

+ 9 - 4
x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpClient.java

@@ -8,6 +8,7 @@
 package org.elasticsearch.xpack.inference.external.http;
 
 import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.protocol.HttpClientContext;
 import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
@@ -56,14 +57,18 @@ public class HttpClient implements Closeable {
         PoolingNHttpClientConnectionManager connectionManager,
         ThrottlerManager throttlerManager
     ) {
-        CloseableHttpAsyncClient client = createAsyncClient(Objects.requireNonNull(connectionManager));
+        var client = createAsyncClient(Objects.requireNonNull(connectionManager), Objects.requireNonNull(settings));
 
         return new HttpClient(settings, client, threadPool, throttlerManager);
     }
 
-    private static CloseableHttpAsyncClient createAsyncClient(PoolingNHttpClientConnectionManager connectionManager) {
-        HttpAsyncClientBuilder clientBuilder = HttpAsyncClientBuilder.create();
-        clientBuilder.setConnectionManager(connectionManager);
+    private static CloseableHttpAsyncClient createAsyncClient(
+        PoolingNHttpClientConnectionManager connectionManager,
+        HttpSettings settings
+    ) {
+        var requestConfig = RequestConfig.custom().setConnectTimeout(settings.connectionTimeout()).build();
+
+        var clientBuilder = HttpAsyncClientBuilder.create().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig);
         // The apache client will be shared across all connections because it can be expensive to create it
         // so we don't want to support cookies to avoid accidental authentication for unauthorized users
         clientBuilder.disableCookieManagement();

+ 15 - 1
x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpSettings.java

@@ -12,6 +12,7 @@ import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.ByteSizeUnit;
 import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.core.TimeValue;
 
 import java.util.List;
 import java.util.Objects;
@@ -27,12 +28,21 @@ public class HttpSettings {
         Setting.Property.Dynamic
     );
 
+    // The time we wait for a connection to establish
+    public static final Setting<TimeValue> CONNECTION_TIMEOUT = Setting.timeSetting(
+        "xpack.inference.http.connect_timeout",
+        TimeValue.timeValueSeconds(5),
+        Setting.Property.NodeScope
+    );
+
     private volatile ByteSizeValue maxResponseSize;
+    private final int connectionTimeout;
 
     public HttpSettings(Settings settings, ClusterService clusterService) {
         Objects.requireNonNull(clusterService);
         Objects.requireNonNull(settings);
         maxResponseSize = MAX_HTTP_RESPONSE_SIZE.get(settings);
+        connectionTimeout = Math.toIntExact(CONNECTION_TIMEOUT.get(settings).getMillis());
 
         clusterService.getClusterSettings().addSettingsUpdateConsumer(MAX_HTTP_RESPONSE_SIZE, this::setMaxResponseSize);
     }
@@ -41,11 +51,15 @@ public class HttpSettings {
         return maxResponseSize;
     }
 
+    public int connectionTimeout() {
+        return connectionTimeout;
+    }
+
     private void setMaxResponseSize(ByteSizeValue maxResponseSize) {
         this.maxResponseSize = maxResponseSize;
     }
 
     public static List<Setting<?>> getSettingsDefinitions() {
-        return List.of(MAX_HTTP_RESPONSE_SIZE);
+        return List.of(MAX_HTTP_RESPONSE_SIZE, CONNECTION_TIMEOUT);
     }
 }

+ 2 - 2
x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/authorization/ElasticInferenceServiceAuthorizationHandler.java

@@ -29,7 +29,6 @@ import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import static org.elasticsearch.xpack.core.inference.action.InferenceAction.Request.DEFAULT_TIMEOUT;
 import static org.elasticsearch.xpack.inference.services.elastic.ElasticInferenceService.ELASTIC_INFERENCE_SERVICE_IDENTIFIER;
 
 /**
@@ -39,6 +38,7 @@ public class ElasticInferenceServiceAuthorizationHandler {
 
     private static final String FAILED_TO_RETRIEVE_MESSAGE =
         "Failed to retrieve the authorization information from the Elastic Inference Service.";
+    private static final TimeValue DEFAULT_AUTH_TIMEOUT = TimeValue.timeValueMinutes(1);
     private static final ResponseHandler AUTH_RESPONSE_HANDLER = createAuthResponseHandler();
 
     private static ResponseHandler createAuthResponseHandler() {
@@ -110,7 +110,7 @@ public class ElasticInferenceServiceAuthorizationHandler {
 
             var request = new ElasticInferenceServiceAuthorizationRequest(baseUrl, getCurrentTraceInfo());
 
-            sender.sendWithoutQueuing(logger, request, AUTH_RESPONSE_HANDLER, DEFAULT_TIMEOUT, newListener);
+            sender.sendWithoutQueuing(logger, request, AUTH_RESPONSE_HANDLER, DEFAULT_AUTH_TIMEOUT, newListener);
         } catch (Exception e) {
             logger.warn(Strings.format("Retrieving the authorization information encountered an exception: %s", e));
             requestCompleteLatch.countDown();