Skip to content

Commit

Permalink
loadbalancer: move DefaultLoadBalancer out of experimental (#3136)
Browse files Browse the repository at this point in the history
Motivation:

We've had DefaultLoadBalancer running in place of round-robin for
some time and it looks good. It's time to move it into the main
package and prepare to remove RoundRobinLoadBalancer.

Modifications:

Move most of the contents of servicetalk-loadbalancer-experimental
to the servicetalk-loadbalancer package.
  • Loading branch information
bryce-anderson authored Dec 19, 2024
1 parent 36ebeb1 commit e4d4418
Show file tree
Hide file tree
Showing 100 changed files with 85 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.loadbalancer;
package io.servicetalk.client.api;

import io.servicetalk.context.api.ContextMap;

Expand Down
10 changes: 4 additions & 6 deletions servicetalk-examples/docs/modules/ROOT/pages/http/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,18 @@ on via a client filter on the client builder.

[#LoadBalancer]
== LoadBalancer
This example demonstrates how to use and configure the experimental link:{source-root}/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LoadBalancers.java[LoadBalancers]:
This example demonstrates how to use and configure link:{source-root}/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/LoadBalancers.java[LoadBalancers]:

- by using link:{source-root}/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LoadBalancerBuilder.java[LoadBalancerBuilder] to customize its setting:
* configuring a different link:{source-root}/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LoadBalancingPolicy.java[LoadBalancingPolicy]
* configuring xDS failure detection using link:{source-root}/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/OutlierDetectorConfig.java[OutlierDetectorConfig]
- by using link:{source-root}/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/LoadBalancerBuilder.java[LoadBalancerBuilder] to customize its setting:
* configuring a different link:{source-root}/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/LoadBalancingPolicy.java[LoadBalancingPolicy]
* configuring xDS failure detection using link:{source-root}/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/OutlierDetectorConfig.java[OutlierDetectorConfig]
- by using link:{source-root}/servicetalk-http-api/src/main/java/io/servicetalk/http/api/DefaultHttpLoadBalancerFactory.java[DefaultHttpLoadBalancerFactory] to adapt a LoadBalancer to HTTP and configure it via client builder

Using the following classes:

- link:{source-root}/servicetalk-examples/http/loadbalancer/src/main/java/io/servicetalk/examples/http/loadbalancer/CustomLoadBalancerClient.java[CustomLoadBalancerClient] - A client that configures custom settings for its LoadBalancer.
- link:{source-root}/servicetalk-examples/http/loadbalancer/src/main/java/io/servicetalk/examples/http/loadbalancer/HelloWorldServer.java[HelloWorldServer] - A simple server implementation.

NOTE: DefaultLoadBalancer is currently considered experimental and therefore the API is subject to change.

[#OpenTracing]
== OpenTracing

Expand Down
2 changes: 1 addition & 1 deletion servicetalk-examples/http/loadbalancer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ apply from: "../../gradle/idea.gradle"
dependencies {
implementation project(":servicetalk-annotations")
implementation project(":servicetalk-http-netty")
implementation project(":servicetalk-loadbalancer-experimental")
implementation project(":servicetalk-loadbalancer")

runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion"
}
1 change: 0 additions & 1 deletion servicetalk-grpc-netty/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ dependencies {
implementation project(":servicetalk-transport-netty-internal")
implementation project(":servicetalk-utils-internal")
implementation project(":servicetalk-concurrent-internal")
implementation project(":servicetalk-loadbalancer-experimental")
implementation "org.slf4j:slf4j-api:$slf4jVersion"
implementation "com.google.protobuf:protobuf-java"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.servicetalk.client.api.ConnectionFactory;
import io.servicetalk.client.api.ConnectionFactoryFilter;
import io.servicetalk.client.api.DelegatingConnectionFactory;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.context.api.ContextMap;
import io.servicetalk.grpc.api.GrpcLifecycleObserver;
Expand All @@ -28,7 +29,6 @@
import io.servicetalk.http.api.HttpRequestMetaData;
import io.servicetalk.http.api.HttpResponseMetaData;
import io.servicetalk.http.netty.HttpLifecycleObserverRequesterFilter;
import io.servicetalk.loadbalancer.RequestTracker;
import io.servicetalk.transport.api.ConnectionInfo;
import io.servicetalk.transport.api.ExecutionStrategy;
import io.servicetalk.transport.api.TransportObserver;
Expand All @@ -40,7 +40,7 @@
import java.util.function.Function;
import javax.annotation.Nullable;

import static io.servicetalk.loadbalancer.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.client.api.RequestTracker.REQUEST_TRACKER_KEY;

final class GrpcRequestTracker {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.servicetalk.grpc.netty;

import io.servicetalk.client.api.DelegatingConnectionFactory;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.concurrent.api.Publisher;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.context.api.ContextMap;
Expand All @@ -25,7 +26,6 @@
import io.servicetalk.grpc.api.GrpcStatusCode;
import io.servicetalk.grpc.api.GrpcStatusException;
import io.servicetalk.http.api.FilterableStreamingHttpConnection;
import io.servicetalk.loadbalancer.RequestTracker;
import io.servicetalk.transport.api.HostAndPort;
import io.servicetalk.transport.api.ServerContext;
import io.servicetalk.transport.api.TransportObserver;
Expand All @@ -40,7 +40,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;

import static io.servicetalk.loadbalancer.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.client.api.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.transport.netty.internal.AddressUtils.localAddress;
import static io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down
1 change: 0 additions & 1 deletion servicetalk-http-netty/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ dependencies {
implementation project(":servicetalk-dns-discovery-netty")
implementation project(":servicetalk-http-utils")
implementation project(":servicetalk-loadbalancer")
implementation project(":servicetalk-loadbalancer-experimental")
implementation project(":servicetalk-loadbalancer-experimental-provider")
implementation project(":servicetalk-logging-slf4j-internal")
implementation project(":servicetalk-tcp-netty-internal")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import io.servicetalk.client.api.ConnectionFactory;
import io.servicetalk.client.api.ConnectionFactoryFilter;
import io.servicetalk.client.api.DelegatingConnectionFactory;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.context.api.ContextMap;
import io.servicetalk.http.api.FilterableStreamingHttpConnection;
import io.servicetalk.http.api.HttpHeaders;
import io.servicetalk.http.api.HttpLifecycleObserver;
import io.servicetalk.http.api.HttpRequestMetaData;
import io.servicetalk.http.api.HttpResponseMetaData;
import io.servicetalk.loadbalancer.RequestTracker;
import io.servicetalk.transport.api.ConnectionInfo;
import io.servicetalk.transport.api.ExecutionStrategy;
import io.servicetalk.transport.api.TransportObserver;
Expand All @@ -38,11 +38,11 @@
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import javax.annotation.Nullable;

import static io.servicetalk.client.api.RequestTracker.ErrorClass.EXT_ORIGIN_TIMEOUT;
import static io.servicetalk.client.api.RequestTracker.ErrorClass.LOCAL_ORIGIN_REQUEST_FAILED;
import static io.servicetalk.client.api.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.http.api.HttpResponseStatus.StatusClass.SERVER_ERROR_5XX;
import static io.servicetalk.http.api.HttpResponseStatus.TOO_MANY_REQUESTS;
import static io.servicetalk.loadbalancer.RequestTracker.ErrorClass.EXT_ORIGIN_TIMEOUT;
import static io.servicetalk.loadbalancer.RequestTracker.ErrorClass.LOCAL_ORIGIN_REQUEST_FAILED;
import static io.servicetalk.loadbalancer.RequestTracker.REQUEST_TRACKER_KEY;

final class HttpRequestTracker {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
package io.servicetalk.http.netty;

import io.servicetalk.client.api.DelegatingConnectionFactory;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.context.api.ContextMap;
import io.servicetalk.http.api.FilterableStreamingHttpConnection;
import io.servicetalk.http.api.HttpClient;
import io.servicetalk.http.api.HttpResponse;
import io.servicetalk.http.api.HttpService;
import io.servicetalk.http.api.SingleAddressHttpClientBuilder;
import io.servicetalk.loadbalancer.RequestTracker;
import io.servicetalk.transport.api.HostAndPort;
import io.servicetalk.transport.api.ServerContext;
import io.servicetalk.transport.api.TransportObserver;
Expand All @@ -39,7 +39,7 @@

import static io.netty.handler.codec.http.HttpStatusClass.SERVER_ERROR;
import static io.netty.handler.codec.http.HttpStatusClass.SUCCESS;
import static io.servicetalk.loadbalancer.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.client.api.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.transport.netty.internal.AddressUtils.localAddress;
import static io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ dependencies {

implementation project(":servicetalk-annotations")
implementation project(":servicetalk-loadbalancer")
implementation project(":servicetalk-loadbalancer-experimental")
implementation "org.slf4j:slf4j-api:$slf4jVersion"
}
23 changes: 4 additions & 19 deletions servicetalk-loadbalancer-experimental/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,9 @@

apply plugin: "io.servicetalk.servicetalk-gradle-plugin-internal-library"

dependencies {
api project(":servicetalk-client-api")
api project(":servicetalk-concurrent-api")

implementation project(":servicetalk-annotations")
implementation project(":servicetalk-concurrent-api-internal")
implementation project(":servicetalk-concurrent-internal")
implementation project(":servicetalk-loadbalancer")
implementation project(":servicetalk-utils-internal")
implementation "org.slf4j:slf4j-api:$slf4jVersion"
tasks.named("javadoc").configure {
enabled = false
}

testImplementation enforcedPlatform("org.junit:junit-bom:$junit5Version")
testImplementation testFixtures(project(":servicetalk-concurrent-api"))
testImplementation testFixtures(project(":servicetalk-concurrent-internal"))
testImplementation project(":servicetalk-concurrent-test-internal")
testImplementation project(":servicetalk-test-resources")
testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testImplementation "org.hamcrest:hamcrest:$hamcrestVersion"
testImplementation "org.mockito:mockito-core:$mockitoCoreVersion"
dependencies {
}
5 changes: 1 addition & 4 deletions servicetalk-loadbalancer-experimental/gradle.lockfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath
org.jctools:jctools-core:4.0.3=runtimeClasspath
org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath
empty=annotationProcessor,spotbugsPlugins,testAnnotationProcessor
empty=annotationProcessor,compileClasspath,runtimeClasspath
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,4 @@
<suppressions>
<!-- No need for package-info.java file because we reuse the package where this file already exists -->
<suppress checks="JavadocPackage" files=".*[\\/]src[\\/]main[\\/]java[\\/]io[\\/]servicetalk[\\/]loadbalancer.*"/>
<suppress id="MissedElementsAreNonnullByDefault"
files="io[\\/]servicetalk[\\/]loadbalancer[\\/]package-info.java"/>
<suppress checks="LineLength"
files="io[\\/]servicetalk[\\/]loadbalancer[\\/]OutlierDetectorConfig.java"/>
</suppressions>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright © 2024 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.loadbalancer;

// FIXME: 0.43: TL;DR: Remove this module. This package existed to support the DefaultLoadBalancer development which
// has since been merged into the servicetalk-loadbalancer module.
final class PlaceHolder {
private PlaceHolder() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

== What is DefaultLoadBalancer?

https://github.com/apple/servicetalk/blob/main/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java[DefaultLoadBalancer]
https://github.com/apple/servicetalk/blob/main/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java[DefaultLoadBalancer]
is a refactor of the ServiceTalk
https://github.com/apple/servicetalk/blob/main/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/RoundRobinLoadBalancer.java[RoundRobinLoadBalancer]
that is intended to provide a more flexible foundation for building load balancers. It also serves as the basis for new
Expand All @@ -11,7 +11,7 @@ outlier detectors.

=== Relationship Between the LoadBalancer and Connections

The load balancer is structured as a series of https://github.com/apple/servicetalk/blob/main/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/Host.java[Host]'s
The load balancer is structured as a series of https://github.com/apple/servicetalk/blob/main/servicetalk-loadbalancer/src/main/java/io/servicetalk/loadbalancer/Host.java[Host]'s
and those hosts can have many connections. The number of connections to each Host is driven by the number of connections
required to satisfy the request load. Usage of the HTTP/2 protocol will dramatically shrink the necessary number of
connections to each backend, often to 1, and is strongly encouraged.
Expand Down
24 changes: 24 additions & 0 deletions servicetalk-loadbalancer/gradle/checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright © 2024 Apple Inc. and the ServiceTalk project authors
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">

<suppressions>
<suppress checks="LineLength"
files="io[\\/]servicetalk[\\/]loadbalancer[\\/]OutlierDetectorConfig.java"/>
</suppressions>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.RequestTracker;

/**
* An interface for tracking connection establishment measurements.
* This has an intended usage similar to the {@link RequestTracker} but with a focus on connection establishment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.function.Predicate;
import javax.annotation.Nullable;

import static io.servicetalk.client.api.RequestTracker.REQUEST_TRACKER_KEY;
import static io.servicetalk.concurrent.api.AsyncCloseables.toAsyncCloseable;
import static io.servicetalk.concurrent.api.Completable.completed;
import static io.servicetalk.concurrent.api.Publisher.fromIterable;
Expand All @@ -52,7 +53,6 @@
import static io.servicetalk.loadbalancer.ConnectTracker.ErrorClass.CANCELLED;
import static io.servicetalk.loadbalancer.ConnectTracker.ErrorClass.CONNECT_ERROR;
import static io.servicetalk.loadbalancer.ConnectTracker.ErrorClass.CONNECT_TIMEOUT;
import static io.servicetalk.loadbalancer.RequestTracker.REQUEST_TRACKER_KEY;
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.client.api.ScoreSupplier;

import java.util.concurrent.locks.StampedLock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.LoadBalancedConnection;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.client.api.ScoreSupplier;
import io.servicetalk.concurrent.Cancellable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.LoadBalancedConnection;
import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.concurrent.api.Executor;
import io.servicetalk.loadbalancer.LoadBalancerObserver.HostObserver;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.RequestTracker;
import io.servicetalk.client.api.ServiceDiscovererEvent;
import io.servicetalk.concurrent.PublisherSource;
import io.servicetalk.concurrent.api.Processors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.servicetalk.loadbalancer;

import io.servicetalk.client.api.RequestTracker;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
Expand Down
Loading

0 comments on commit e4d4418

Please sign in to comment.