diff --git a/servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/HttpClients.java b/servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/HttpClients.java index 1e9e2a68a5..1adb10a061 100644 --- a/servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/HttpClients.java +++ b/servicetalk-http-netty/src/main/java/io/servicetalk/http/netty/HttpClients.java @@ -28,6 +28,7 @@ import io.servicetalk.concurrent.api.ListenableAsyncCloseable; import io.servicetalk.concurrent.api.Publisher; import io.servicetalk.http.api.DelegatingSingleAddressHttpClientBuilder; +import io.servicetalk.http.api.FilterableStreamingHttpLoadBalancedConnection; import io.servicetalk.http.api.HttpClient; import io.servicetalk.http.api.HttpHeaderNames; import io.servicetalk.http.api.HttpProviders.MultiAddressHttpClientBuilderProvider; @@ -39,6 +40,7 @@ import io.servicetalk.http.api.ProxyConfig; import io.servicetalk.http.api.SingleAddressHttpClientBuilder; import io.servicetalk.http.api.StreamingHttpRequest; +import io.servicetalk.loadbalancer.RoundRobinLoadBalancers; import io.servicetalk.transport.api.HostAndPort; import io.servicetalk.transport.api.TransportObserver; @@ -451,6 +453,15 @@ private static SingleAddressHttpClientBuilder forSingleAddress( // Apply after providers to let them see these customizations. .serviceDiscoverer(usd) .retryServiceDiscoveryErrors(NoRetriesStrategy.INSTANCE) + // Disable health-checking: + .loadBalancerFactory(DefaultHttpLoadBalancerFactory.Builder.from( + RoundRobinLoadBalancers.builder( + // Use a different ID to let providers distinguish this LB from the default one + DefaultHttpLoadBalancerFactory.class.getSimpleName() + '-' + + DiscoveryStrategy.ON_NEW_CONNECTION.name()) + .healthCheckFailedConnectionsThreshold(-1) + .build()) + .build()) .appendConnectionFactoryFilter(resolvingConnectionFactory.get()); default: throw new IllegalArgumentException("Unsupported strategy: " + discoveryStrategy); diff --git a/servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/HttpClientResolvesOnNewConnectionTest.java b/servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/HttpClientResolvesOnNewConnectionTest.java index da17752f46..51b70e2859 100644 --- a/servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/HttpClientResolvesOnNewConnectionTest.java +++ b/servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/HttpClientResolvesOnNewConnectionTest.java @@ -152,6 +152,18 @@ void attemptToOverrideServiceDiscovererThrows() { assertThat(e.getMessage(), allOf(containsString(ON_NEW_CONNECTION.name()), containsString(otherSd.toString()))); } + @Test + void noHealthChecking() throws Exception { + try (BlockingHttpClient client = HttpClients.forSingleAddress(FailureCase.SERVICE_DISCOVERER_FAILED.customSd, + new UnresolvedAddress(null), ON_NEW_CONNECTION).buildBlocking()) { + // The default health-checking threshold is 5, validate that client doesn't start returning + // NoActiveHostException instead of DeliberateException after 5 attempts + for (int i = 0; i < 10; i++) { + assertThrows(DeliberateException.class, () -> client.request(client.get("/"))); + } + } + } + @ParameterizedTest(name = "{displayName} [{index}]: failureCase={0}") @EnumSource(FailureCase.class) void failureCases(FailureCase failureCase) throws Exception {