From 69c9cb30b83bcbf3ca3e11c1e66cc215ba97c1b8 Mon Sep 17 00:00:00 2001 From: Bryce Anderson Date: Fri, 6 Dec 2024 09:33:52 -0700 Subject: [PATCH] loadbalancer-experimental: rename ConnectionPoolStrategy -> ConnectionSelector (#3130) Motivation: The ConnectionPoolStrategy carries a lot of parallels with the HostSelector abstraction, in that it's goal is to select a connection. However, the names are dissimilar and 'Strategy' doesn't have as strong an implication of being capable of action. Modifications: Rename ConnectionPoolStrategy to ConnectionSelector to make its role more clear. --- .../loadbalancer/ConnectionPoolPolicy.java | 30 +++++------ ...lStrategy.java => ConnectionSelector.java} | 18 +++---- ...y.java => CorePoolConnectionSelector.java} | 24 ++++----- .../servicetalk/loadbalancer/DefaultHost.java | 8 +-- .../loadbalancer/DefaultLoadBalancer.java | 12 ++--- .../DefaultLoadBalancerBuilder.java | 54 +++++++++---------- ...va => LinearSearchConnectionSelector.java} | 22 ++++---- ...rategy.java => P2CConnectionSelector.java} | 26 ++++----- ...rs.java => ConnectionSelectorHelpers.java} | 4 +- ...va => CorePoolConnectionSelectorTest.java} | 18 +++---- .../loadbalancer/DefaultHostTest.java | 4 +- .../loadbalancer/DefaultLoadBalancerTest.java | 2 +- ...> LinearSearchConnectionSelectorTest.java} | 16 +++--- ...st.java => P2CConnectionSelectorTest.java} | 20 +++---- 14 files changed, 129 insertions(+), 129 deletions(-) rename servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/{ConnectionPoolStrategy.java => ConnectionSelector.java} (68%) rename servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/{CorePoolConnectionPoolStrategy.java => CorePoolConnectionSelector.java} (79%) rename servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/{LinearSearchConnectionPoolStrategy.java => LinearSearchConnectionSelector.java} (81%) rename servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/{P2CConnectionPoolStrategy.java => P2CConnectionSelector.java} (85%) rename servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/{ConnectionPoolStrategyHelpers.java => ConnectionSelectorHelpers.java} (91%) rename servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/{CorePoolConnectionPoolStrategyTest.java => CorePoolConnectionSelectorTest.java} (81%) rename servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/{LinearSearchConnectionPoolStrategyTest.java => LinearSearchConnectionSelectorTest.java} (75%) rename servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/{P2CConnectionPoolStrategyTest.java => P2CConnectionSelectorTest.java} (83%) diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolPolicy.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolPolicy.java index 47dff4ee03..5caaabba29 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolPolicy.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolPolicy.java @@ -18,7 +18,7 @@ import static io.servicetalk.utils.internal.NumberUtils.ensurePositive; /** - * Configuration of the strategy for selecting connections from a pool to the same endpoint. + * Configuration of the policy for selecting connections from a pool to the same endpoint. */ public abstract class ConnectionPoolPolicy { @@ -30,7 +30,7 @@ private ConnectionPoolPolicy() { } /** - * A connection selection strategy that prioritizes a configurable "core" pool. + * A connection selection policy that prioritizes a configurable "core" pool. *

* This {@link ConnectionPoolPolicy} attempts to emulate the pooling behavior often seen in thread pools. * Specifically it allows for the configuration of a "core pool" size which are intended to be long-lived. @@ -49,11 +49,11 @@ private ConnectionPoolPolicy() { * @return the configured {@link ConnectionPoolPolicy}. */ public static ConnectionPoolPolicy corePool(final int corePoolSize, final boolean forceCorePool) { - return new CorePoolStrategy(corePoolSize, forceCorePool); + return new CorePoolPolicy(corePoolSize, forceCorePool); } /** - * A connection selection strategy that prioritizes connection reuse. + * A connection selection policy that prioritizes connection reuse. *

* This {@link ConnectionPoolPolicy} attempts to minimize the number of connections by attempting to direct * traffic to connections in the order they were created in linear order up until a configured quantity. After @@ -66,7 +66,7 @@ public static ConnectionPoolPolicy linearSearch() { } /** - * A connection selection strategy that prioritizes connection reuse. + * A connection selection policy that prioritizes connection reuse. *

* This {@link ConnectionPoolPolicy} attempts to minimize the number of connections by attempting to direct * traffic to connections in the order they were created in linear order up until a configured quantity. After @@ -77,12 +77,12 @@ public static ConnectionPoolPolicy linearSearch() { * @return the configured {@link ConnectionPoolPolicy}. */ public static ConnectionPoolPolicy linearSearch(int linearSearchSpace) { - return new LinearSearchStrategy(linearSearchSpace); + return new LinearSearchPolicy(linearSearchSpace); } /** * A {@link ConnectionPoolPolicy} that attempts to discern between the health of individual connections. - * If individual connections have health data the P2C strategy can be used to bias traffic toward the best + * If individual connections have health data the P2C policy can be used to bias traffic toward the best * connections. This has the following algorithm: * - Randomly select two connections from the 'core pool' (pick-two). * - Try to select the 'best' of the two connections. @@ -100,7 +100,7 @@ public static ConnectionPoolPolicy p2c(int corePoolSize, boolean forceCorePool) /** * A {@link ConnectionPoolPolicy} that attempts to discern between the health of individual connections. - * If individual connections have health data the P2C strategy can be used to bias traffic toward the best + * If individual connections have health data the P2C policy can be used to bias traffic toward the best * connections. This has the following algorithm: * - Randomly select two connections from the 'core pool' (pick-two). * - Try to select the 'best' of the two connections. @@ -114,36 +114,36 @@ public static ConnectionPoolPolicy p2c(int corePoolSize, boolean forceCorePool) * @return the configured {@link ConnectionPoolPolicy}. */ public static ConnectionPoolPolicy p2c(int maxEffort, int corePoolSize, boolean forceCorePool) { - return new P2CStrategy(maxEffort, corePoolSize, forceCorePool); + return new P2CPolicy(maxEffort, corePoolSize, forceCorePool); } // instance types - static final class CorePoolStrategy extends ConnectionPoolPolicy { + static final class CorePoolPolicy extends ConnectionPoolPolicy { final int corePoolSize; final boolean forceCorePool; - CorePoolStrategy(final int corePoolSize, final boolean forceCorePool) { + CorePoolPolicy(final int corePoolSize, final boolean forceCorePool) { this.corePoolSize = ensurePositive(corePoolSize, "corePoolSize"); this.forceCorePool = forceCorePool; } } - static final class P2CStrategy extends ConnectionPoolPolicy { + static final class P2CPolicy extends ConnectionPoolPolicy { final int maxEffort; final int corePoolSize; final boolean forceCorePool; - P2CStrategy(final int maxEffort, final int corePoolSize, final boolean forceCorePool) { + P2CPolicy(final int maxEffort, final int corePoolSize, final boolean forceCorePool) { this.maxEffort = ensurePositive(maxEffort, "maxEffort"); this.corePoolSize = ensurePositive(corePoolSize, "corePoolSize"); this.forceCorePool = forceCorePool; } } - static final class LinearSearchStrategy extends ConnectionPoolPolicy { + static final class LinearSearchPolicy extends ConnectionPoolPolicy { final int linearSearchSpace; - LinearSearchStrategy(int linearSearchSpace) { + LinearSearchPolicy(int linearSearchSpace) { this.linearSearchSpace = ensurePositive(linearSearchSpace, "linearSearchSpace"); } } diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolStrategy.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionSelector.java similarity index 68% rename from servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolStrategy.java rename to servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionSelector.java index 07b50cd9b5..c22ad7f146 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionPoolStrategy.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/ConnectionSelector.java @@ -22,10 +22,10 @@ import javax.annotation.Nullable; /** - * A strategy for selecting connections at the {@link Host} level connection pool. + * An abstraction for selecting connections at the {@link Host} level connection pool. * @param the concrete type of the connection. */ -interface ConnectionPoolStrategy { +interface ConnectionSelector { /** * Select a connection from the ordered list of connections. @@ -37,18 +37,18 @@ interface ConnectionPoolStrategy { C select(List connections, Predicate selector); /** - * The factory of {@link ConnectionPoolStrategy} instances. - * @param the least specific connection type necessary for properly implementing the strategy. - * @see ConnectionPoolStrategy for available strategies. + * The factory of {@link ConnectionSelector} instances. + * @param the least specific connection type necessary for properly implementing the selector. + * @see ConnectionSelector for available strategies. */ - interface ConnectionPoolStrategyFactory { + interface ConnectionSelectorFactory { /** - * Provide an instance of the {@link ConnectionPoolStrategy} to use with a {@link Host}. + * Provide an instance of the {@link ConnectionSelector} to use with a {@link Host}. * @param lbDescription description of the resource, used for logging purposes. - * @return an instance of the {@link ConnectionPoolStrategy} to use with a {@link Host}. + * @return an instance of the {@link ConnectionSelector} to use with a {@link Host}. */ - ConnectionPoolStrategy buildStrategy(String lbDescription); + ConnectionSelector buildConnectionSelector(String lbDescription); } } diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategy.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionSelector.java similarity index 79% rename from servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategy.java rename to servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionSelector.java index 1785854c0c..4798a4999e 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategy.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/CorePoolConnectionSelector.java @@ -28,7 +28,7 @@ /** * A connection selection strategy that prioritizes a configurable "core" pool. *

- * This {@link ConnectionPoolStrategy} attempts to emulate the pooling behavior often seen in thread pools. + * This {@link ConnectionSelector} attempts to emulate the pooling behavior often seen in thread pools. * Specifically it allows for the configuration of a "core pool" size which are intended to be long-lived. * Iteration starts in the core pool at a random position and then iterates through the entire core pool before * moving to an overflow pool. Because iteration of this core pool starts at a random position the core connections @@ -40,13 +40,13 @@ * * @param the concrete type of the {@link LoadBalancedConnection}. */ -final class CorePoolConnectionPoolStrategy - implements ConnectionPoolStrategy { +final class CorePoolConnectionSelector + implements ConnectionSelector { private final int corePoolSize; private final boolean forceCorePool; - private CorePoolConnectionPoolStrategy(final int corePoolSize, final boolean forceCorePool) { + private CorePoolConnectionSelector(final int corePoolSize, final boolean forceCorePool) { this.corePoolSize = ensurePositive(corePoolSize, "corePoolSize"); this.forceCorePool = forceCorePool; } @@ -83,30 +83,30 @@ public C select(List connections, Predicate selector) { return null; } - static ConnectionPoolStrategyFactory factory( + static ConnectionSelectorFactory factory( int corePoolSize, boolean forceCorePool) { - return new CorePoolConnectionPoolStrategyFactory<>(corePoolSize, forceCorePool); + return new CorePoolConnectionSelectorFactory<>(corePoolSize, forceCorePool); } - private static final class CorePoolConnectionPoolStrategyFactory - implements ConnectionPoolStrategyFactory { + private static final class CorePoolConnectionSelectorFactory + implements ConnectionSelectorFactory { private final int corePoolSize; private final boolean forceCorePool; - CorePoolConnectionPoolStrategyFactory(int corePoolSize, boolean forceCorePool) { + CorePoolConnectionSelectorFactory(int corePoolSize, boolean forceCorePool) { this.corePoolSize = ensurePositive(corePoolSize, "corePoolSize"); this.forceCorePool = forceCorePool; } @Override - public ConnectionPoolStrategy buildStrategy(String lbDescription) { - return new CorePoolConnectionPoolStrategy<>(corePoolSize, forceCorePool); + public ConnectionSelector buildConnectionSelector(String lbDescription) { + return new CorePoolConnectionSelector<>(corePoolSize, forceCorePool); } @Override public String toString() { - return "CorePoolConnectionPoolStrategyFactory{" + + return CorePoolConnectionSelectorFactory.class.getSimpleName() + "{" + "corePoolSize=" + corePoolSize + ", forceCorePool=" + forceCorePool + '}'; diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultHost.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultHost.java index 6ff63dfb03..e358e01c4a 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultHost.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultHost.java @@ -85,7 +85,7 @@ private enum State { private final Addr address; @Nullable private final HealthCheckConfig healthCheckConfig; - private final ConnectionPoolStrategy connectionPoolStrategy; + private final ConnectionSelector connectionSelector; @Nullable private final HealthIndicator healthIndicator; private final LoadBalancerObserver.HostObserver hostObserver; @@ -94,14 +94,14 @@ private enum State { private volatile ConnState connState = new ConnState(emptyList(), State.ACTIVE, 0, null); DefaultHost(final String lbDescription, final Addr address, - final ConnectionPoolStrategy connectionPoolStrategy, + final ConnectionSelector connectionSelector, final ConnectionFactory connectionFactory, final HostObserver hostObserver, @Nullable final HealthCheckConfig healthCheckConfig, @Nullable final HealthIndicator healthIndicator) { this.lbDescription = requireNonNull(lbDescription, "lbDescription"); this.address = requireNonNull(address, "address"); this.healthIndicator = healthIndicator; - this.connectionPoolStrategy = requireNonNull(connectionPoolStrategy, "connectionPoolStrategy"); + this.connectionSelector = requireNonNull(connectionSelector, "connectionSelector"); requireNonNull(connectionFactory, "connectionFactory"); this.connectionFactory = healthIndicator == null ? connectionFactory : new InstrumentedConnectionFactory<>(connectionFactory, healthIndicator); @@ -181,7 +181,7 @@ public boolean markExpired() { @Nullable public C pickConnection(Predicate selector, @Nullable final ContextMap context) { final List connections = connState.connections; - return connectionPoolStrategy.select(connections, selector); + return connectionSelector.select(connections, selector); } @Override diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java index 14d6881677..6e68308742 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java @@ -109,7 +109,7 @@ final class DefaultLoadBalancer eventStreamProcessor = newPublisherProcessorDropHeadOnOverflow(32); private final Publisher eventStream; private final SequentialCancellable discoveryCancellable = new SequentialCancellable(); - private final ConnectionPoolStrategy connectionPoolStrategy; + private final ConnectionSelector connectionSelector; private final ConnectionFactory connectionFactory; private final int randomSubsetSize; @Nullable @@ -130,7 +130,7 @@ final class DefaultLoadBalancer priorityStrategyFactory, final LoadBalancingPolicy loadBalancingPolicy, final int randomSubsetSize, - final ConnectionPoolStrategy.ConnectionPoolStrategyFactory connectionPoolStrategyFactory, + final ConnectionSelector.ConnectionSelectorFactory connectionSelectorFactory, final ConnectionFactory connectionFactory, final LoadBalancerObserverFactory loadBalancerObserverFactory, @Nullable final HealthCheckConfig healthCheckConfig, @@ -157,8 +157,8 @@ final class DefaultLoadBalancer createHost(ServiceDiscovererEven final HealthCheckConfig hostHealthCheckConfig = healthCheckConfig == null || healthCheckConfig.failedThreshold < 0 ? null : healthCheckConfig; final PrioritizedHostImpl host = new PrioritizedHostImpl<>( - new DefaultHost<>(lbDescription, addr, connectionPoolStrategy, + new DefaultHost<>(lbDescription, addr, connectionSelector, connectionFactory, hostObserver, hostHealthCheckConfig, indicator), eventWeight(event), eventPriority(event)); if (indicator != null) { diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancerBuilder.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancerBuilder.java index 18661637e9..1e0c779497 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancerBuilder.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancerBuilder.java @@ -22,7 +22,7 @@ import io.servicetalk.client.api.ServiceDiscovererEvent; import io.servicetalk.concurrent.api.Executor; import io.servicetalk.concurrent.api.Publisher; -import io.servicetalk.loadbalancer.ConnectionPoolStrategy.ConnectionPoolStrategyFactory; +import io.servicetalk.loadbalancer.ConnectionSelector.ConnectionSelectorFactory; import io.servicetalk.transport.api.ExecutionStrategy; import java.util.Collection; @@ -43,7 +43,7 @@ final class DefaultLoadBalancerBuilder connectionPoolStrategyFactory = defaultConnectionPoolStrategyFactory(); + private ConnectionSelectorFactory connectionSelectorFactory = defaultConnectionSelectorFactory(); private OutlierDetectorConfig outlierDetectorConfig = OutlierDetectorConfig.DEFAULT_CONFIG; // package private constructor so users must funnel through providers in `LoadBalancers` @@ -80,7 +80,7 @@ public LoadBalancerBuilder outlierDetectorConfig(OutlierDete @Override public LoadBalancerBuilder connectionPoolPolicy( ConnectionPoolPolicy connectionPoolPolicy) { - this.connectionPoolStrategyFactory = convertPoolStrategy(requireNonNull(connectionPoolPolicy, + this.connectionSelectorFactory = convertPoolPolicy(requireNonNull(connectionPoolPolicy, "connectionPoolPolicy")); return this; } @@ -94,7 +94,7 @@ public LoadBalancerBuilder backgroundExecutor(Executor backg @Override public LoadBalancerFactory build() { return new DefaultLoadBalancerFactory<>(id, loadBalancingPolicy, randomSubsetSize, loadBalancerObserverFactory, - connectionPoolStrategyFactory, outlierDetectorConfig, getExecutor()); + connectionSelectorFactory, outlierDetectorConfig, getExecutor()); } static final class DefaultLoadBalancerFactory @@ -105,14 +105,14 @@ static final class DefaultLoadBalancerFactory connectionPoolStrategyFactory; + private final ConnectionSelectorFactory connectionSelectorFactory; private final OutlierDetectorConfig outlierDetectorConfig; private final Executor executor; DefaultLoadBalancerFactory(final String id, final LoadBalancingPolicy loadBalancingPolicy, final int subsetSize, @Nullable final LoadBalancerObserverFactory loadBalancerObserverFactory, - final ConnectionPoolStrategyFactory connectionPoolStrategyFactory, + final ConnectionSelectorFactory connectionSelectorFactory, final OutlierDetectorConfig outlierDetectorConfig, final Executor executor) { this.id = requireNonNull(id, "id"); @@ -120,8 +120,8 @@ static final class DefaultLoadBalancerFactory newLoadBalancer( } return new DefaultLoadBalancer<>(id, targetResource, eventPublisher, DefaultHostPriorityStrategy::new, loadBalancingPolicy, subsetSize, - connectionPoolStrategyFactory, connectionFactory, + connectionSelectorFactory, connectionFactory, loadBalancerObserverFactory, healthCheckConfig, outlierDetectorFactory); } @@ -184,7 +184,7 @@ public String toString() { "id='" + id + '\'' + ", loadBalancingPolicy=" + loadBalancingPolicy + ", loadBalancerObserverFactory=" + loadBalancerObserverFactory + - ", connectionPoolStrategyFactory=" + connectionPoolStrategyFactory + + ", connectionSelectorFactory=" + connectionSelectorFactory + ", outlierDetectorConfig=" + outlierDetectorConfig + ", executor=" + executor + '}'; @@ -196,22 +196,22 @@ private Executor getExecutor() { null ? RoundRobinLoadBalancerFactory.SharedExecutor.getInstance() : backgroundExecutor; } - private static ConnectionPoolStrategyFactory convertPoolStrategy( - ConnectionPoolPolicy connectionPoolStrategyConfig) { - if (connectionPoolStrategyConfig instanceof ConnectionPoolPolicy.P2CStrategy) { - ConnectionPoolPolicy.P2CStrategy strategy = (ConnectionPoolPolicy.P2CStrategy) connectionPoolStrategyConfig; - return P2CConnectionPoolStrategy.factory(strategy.maxEffort, strategy.corePoolSize, strategy.forceCorePool); - } else if (connectionPoolStrategyConfig instanceof ConnectionPoolPolicy.CorePoolStrategy) { - ConnectionPoolPolicy.CorePoolStrategy strategy = - (ConnectionPoolPolicy.CorePoolStrategy) connectionPoolStrategyConfig; - return CorePoolConnectionPoolStrategy.factory(strategy.corePoolSize, strategy.forceCorePool); - } else if (connectionPoolStrategyConfig instanceof ConnectionPoolPolicy.LinearSearchStrategy) { - ConnectionPoolPolicy.LinearSearchStrategy strategy = - (ConnectionPoolPolicy.LinearSearchStrategy) connectionPoolStrategyConfig; - return LinearSearchConnectionPoolStrategy.factory(strategy.linearSearchSpace); + private static ConnectionSelectorFactory convertPoolPolicy( + ConnectionPoolPolicy connectionPoolPolicy) { + if (connectionPoolPolicy instanceof ConnectionPoolPolicy.P2CPolicy) { + ConnectionPoolPolicy.P2CPolicy strategy = (ConnectionPoolPolicy.P2CPolicy) connectionPoolPolicy; + return P2CConnectionSelector.factory(strategy.maxEffort, strategy.corePoolSize, strategy.forceCorePool); + } else if (connectionPoolPolicy instanceof ConnectionPoolPolicy.CorePoolPolicy) { + ConnectionPoolPolicy.CorePoolPolicy strategy = + (ConnectionPoolPolicy.CorePoolPolicy) connectionPoolPolicy; + return CorePoolConnectionSelector.factory(strategy.corePoolSize, strategy.forceCorePool); + } else if (connectionPoolPolicy instanceof ConnectionPoolPolicy.LinearSearchPolicy) { + ConnectionPoolPolicy.LinearSearchPolicy strategy = + (ConnectionPoolPolicy.LinearSearchPolicy) connectionPoolPolicy; + return LinearSearchConnectionSelector.factory(strategy.linearSearchSpace); } else { throw new IllegalStateException("Unexpected ConnectionPoolConfig: " + - connectionPoolStrategyConfig.getClass().getName()); + connectionPoolPolicy.getClass().getName()); } } @@ -220,8 +220,8 @@ LoadBalancingPolicy defaultLoadBalancingPolicy() { return LoadBalancingPolicies.roundRobin().build(); } - private static ConnectionPoolStrategyFactory - defaultConnectionPoolStrategyFactory() { - return convertPoolStrategy(ConnectionPoolPolicy.linearSearch()); + private static ConnectionSelectorFactory + defaultConnectionSelectorFactory() { + return convertPoolPolicy(ConnectionPoolPolicy.linearSearch()); } } diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategy.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelector.java similarity index 81% rename from servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategy.java rename to servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelector.java index 0ef823c4c5..d7a9118001 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategy.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelector.java @@ -28,14 +28,14 @@ /** * A connection selection strategy that prioritizes connection reuse. *

- * This {@link ConnectionPoolStrategy} attempts to minimize the number of connections by attempting to direct + * This {@link ConnectionSelector} attempts to minimize the number of connections by attempting to direct * traffic to connections in the order they were created in linear order up until a configured quantity. After * this linear pool is exhausted the remaining connections will be selected from at random. Prioritizing traffic * to the existing connections will let tailing connections be removed due to idleness. * * @param the concrete type of the {@link LoadBalancedConnection}. */ -final class LinearSearchConnectionPoolStrategy implements ConnectionPoolStrategy { +final class LinearSearchConnectionSelector implements ConnectionSelector { /** * With a relatively small number of connections we can minimize connection creation under moderate concurrency by @@ -56,7 +56,7 @@ final class LinearSearchConnectionPoolStrategy private final int linearSearchSpace; - private LinearSearchConnectionPoolStrategy(final int linearSearchSpace) { + private LinearSearchConnectionSelector(final int linearSearchSpace) { this.linearSearchSpace = ensureNonNegative(linearSearchSpace, "linearSearchSpace"); } @@ -90,27 +90,27 @@ public C select(List connections, Predicate selector) { return null; } - static ConnectionPoolStrategyFactory factory(final int linearSearchSpace) { - return new LinearSearchConnectionPoolStrategyFactory<>(linearSearchSpace); + static ConnectionSelectorFactory factory(final int linearSearchSpace) { + return new LinearSearchConnectionSelectorFactory<>(linearSearchSpace); } - private static final class LinearSearchConnectionPoolStrategyFactory - implements ConnectionPoolStrategyFactory { + private static final class LinearSearchConnectionSelectorFactory + implements ConnectionSelectorFactory { private final int linearSearchSpace; - LinearSearchConnectionPoolStrategyFactory(final int linearSearchSpace) { + LinearSearchConnectionSelectorFactory(final int linearSearchSpace) { this.linearSearchSpace = ensureNonNegative(linearSearchSpace, "linearSearchSpace"); } @Override - public ConnectionPoolStrategy buildStrategy(String lbDescription) { - return new LinearSearchConnectionPoolStrategy<>(linearSearchSpace); + public ConnectionSelector buildConnectionSelector(String lbDescription) { + return new LinearSearchConnectionSelector<>(linearSearchSpace); } @Override public String toString() { - return "LinearSearchConnectionPoolStrategyFactory{" + + return LinearSearchConnectionSelectorFactory.class.getSimpleName() + "{" + "linearSearchSpace=" + linearSearchSpace + '}'; } diff --git a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategy.java b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionSelector.java similarity index 85% rename from servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategy.java rename to servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionSelector.java index ca57b808af..8617fcbeda 100644 --- a/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategy.java +++ b/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/P2CConnectionSelector.java @@ -31,7 +31,7 @@ import static java.util.Objects.requireNonNull; /** - * A {@link ConnectionPoolStrategy} that attempts to discern between the health of individual connections. + * A {@link ConnectionSelector} that attempts to discern between the health of individual connections. * If individual connections have health data the P2C strategy can be used to bias traffic toward the best * connections. This has the following algorithm: * - Randomly select two connections from the 'core pool' (pick-two). @@ -41,17 +41,17 @@ * through the remaining connections searching for an acceptable connection. * @param the type of the load balanced connection. */ -final class P2CConnectionPoolStrategy implements ConnectionPoolStrategy { +final class P2CConnectionSelector implements ConnectionSelector { - private static final Logger LOGGER = LoggerFactory.getLogger(P2CConnectionPoolStrategy.class); + private static final Logger LOGGER = LoggerFactory.getLogger(P2CConnectionSelector.class); private final String lbDescription; private final int maxEffort; private final int corePoolSize; private final boolean forceCorePool; - private P2CConnectionPoolStrategy(final String lbDescription, final int maxEffort, final int corePoolSize, - final boolean forceCorePool) { + private P2CConnectionSelector(final String lbDescription, final int maxEffort, final int corePoolSize, + final boolean forceCorePool) { this.lbDescription = requireNonNull(lbDescription, "lbDescription"); this.maxEffort = ensureNonNegative(maxEffort, "maxEffort"); this.corePoolSize = ensureNonNegative(corePoolSize, "corePoolSize"); @@ -139,19 +139,19 @@ private C p2cPick(ThreadLocalRandom rnd, int randomSearchSpace, List connecti return null; } - static ConnectionPoolStrategyFactory factory( + static ConnectionSelectorFactory factory( final int maxEffort, final int corePoolSize, final boolean forceCorePool) { - return new P2CConnectionPoolStrategyFactory<>(maxEffort, corePoolSize, forceCorePool); + return new P2CConnectionSelectorFactory<>(maxEffort, corePoolSize, forceCorePool); } - private static final class P2CConnectionPoolStrategyFactory - implements ConnectionPoolStrategyFactory { + private static final class P2CConnectionSelectorFactory + implements ConnectionSelectorFactory { private final int maxEffort; private final int corePoolSize; private final boolean forceCorePool; - P2CConnectionPoolStrategyFactory( + P2CConnectionSelectorFactory( final int maxEffort, final int corePoolSize, final boolean forceCorePool) { this.maxEffort = ensurePositive(maxEffort, " maxEffort"); this.corePoolSize = ensureNonNegative(corePoolSize, "corePoolSize"); @@ -159,13 +159,13 @@ private static final class P2CConnectionPoolStrategyFactory buildStrategy(String lbDescription) { - return new P2CConnectionPoolStrategy<>(lbDescription, maxEffort, corePoolSize, forceCorePool); + public ConnectionSelector buildConnectionSelector(String lbDescription) { + return new P2CConnectionSelector<>(lbDescription, maxEffort, corePoolSize, forceCorePool); } @Override public String toString() { - return "P2CConnectionPoolStrategyFactory{" + + return P2CConnectionSelectorFactory.class.getSimpleName() + "{" + "maxEffort=" + maxEffort + ", corePoolSize=" + corePoolSize + ", forceCorePool=" + forceCorePool + diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionPoolStrategyHelpers.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionSelectorHelpers.java similarity index 91% rename from servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionPoolStrategyHelpers.java rename to servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionSelectorHelpers.java index fa3d09a4bc..f63084f0cc 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionPoolStrategyHelpers.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/ConnectionSelectorHelpers.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import java.util.List; -public final class ConnectionPoolStrategyHelpers { +final class ConnectionSelectorHelpers { - private ConnectionPoolStrategyHelpers() { + private ConnectionSelectorHelpers() { // no instances } diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategyTest.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionSelectorTest.java similarity index 81% rename from servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategyTest.java rename to servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionSelectorTest.java index dab2c1d12d..aed1b5adec 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionPoolStrategyTest.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/CorePoolConnectionSelectorTest.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.function.Predicate; -import static io.servicetalk.loadbalancer.ConnectionPoolStrategyHelpers.makeConnections; +import static io.servicetalk.loadbalancer.ConnectionSelectorHelpers.makeConnections; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasItem; @@ -32,18 +32,18 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -class CorePoolConnectionPoolStrategyTest { +class CorePoolConnectionSelectorTest { - private ConnectionPoolStrategy strategy(int corePoolSize, boolean forceCorePool) { - return CorePoolConnectionPoolStrategy.factory(corePoolSize, forceCorePool) - .buildStrategy("resource"); + private ConnectionSelector strategy(int corePoolSize, boolean forceCorePool) { + return CorePoolConnectionSelector.factory(corePoolSize, forceCorePool) + .buildConnectionSelector("resource"); } @Test void selectsHosts() { for (int i = 1; i < 10; i++) { List connections = makeConnections(i); - ConnectionPoolStrategy strategy = strategy(5, false); + ConnectionSelector strategy = strategy(5, false); assertNotNull(strategy.select(connections, c -> true)); } } @@ -51,7 +51,7 @@ void selectsHosts() { @Test void prefersCorePool() { List connections = makeConnections(10); - ConnectionPoolStrategy strategy = strategy(5, false); + ConnectionSelector strategy = strategy(5, false); Set selected = new HashSet<>(); for (int i = 0; i < 100; i++) { selected.add(strategy.select(connections, c -> true)); @@ -69,7 +69,7 @@ void prefersCorePool() { @Test void spillsIntoOverflow() { List connections = makeConnections(6); - ConnectionPoolStrategy strategy = strategy(5, false); + ConnectionSelector strategy = strategy(5, false); Set corePoolCxns = new HashSet<>(); for (int i = 0; i < 5; i++) { corePoolCxns.add(connections.get(i)); @@ -82,7 +82,7 @@ void spillsIntoOverflow() { void forcingCorePoolWillEnsureCorePoolGrows() { List connections = makeConnections(5); for (int i = 1; i < 10; i++) { - ConnectionPoolStrategy strategy = strategy(i, true); + ConnectionSelector strategy = strategy(i, true); if (i <= 5) { // core pool large enough assertNotNull(strategy.select(connections, c -> true)); diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultHostTest.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultHostTest.java index 45d22c0d59..45382472ec 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultHostTest.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultHostTest.java @@ -82,8 +82,8 @@ void cleanup() { private void buildHost(@Nullable HealthIndicator healthIndicator) { host = new DefaultHost<>("lbDescription", DEFAULT_ADDRESS, - LinearSearchConnectionPoolStrategy.factory(DEFAULT_LINEAR_SEARCH_SPACE) - .buildStrategy("resource"), + LinearSearchConnectionSelector.factory(DEFAULT_LINEAR_SEARCH_SPACE) + .buildConnectionSelector("resource"), connectionFactory, mockHostObserver, healthCheckConfig, healthIndicator); } diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultLoadBalancerTest.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultLoadBalancerTest.java index 2be4b5504a..70b2955f15 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultLoadBalancerTest.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/DefaultLoadBalancerTest.java @@ -317,7 +317,7 @@ TestableLoadBalancer newTestLoadBalancer( hostPriorityStrategyFactory, loadBalancingPolicy, subsetSize, - LinearSearchConnectionPoolStrategy.factory(DEFAULT_LINEAR_SEARCH_SPACE), + LinearSearchConnectionSelector.factory(DEFAULT_LINEAR_SEARCH_SPACE), connectionFactory, NoopLoadBalancerObserver.factory(), null, diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategyTest.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelectorTest.java similarity index 75% rename from servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategyTest.java rename to servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelectorTest.java index 9067d46027..11917ed2b9 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionPoolStrategyTest.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/LinearSearchConnectionSelectorTest.java @@ -21,15 +21,15 @@ import java.util.List; import java.util.Set; -import static io.servicetalk.loadbalancer.ConnectionPoolStrategyHelpers.makeConnections; +import static io.servicetalk.loadbalancer.ConnectionSelectorHelpers.makeConnections; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -class LinearSearchConnectionPoolStrategyTest { +class LinearSearchConnectionSelectorTest { - ConnectionPoolStrategy strategy(int linearSearchSpace) { - return LinearSearchConnectionPoolStrategy.factory(linearSearchSpace) - .buildStrategy("resource"); + ConnectionSelector strategy(int linearSearchSpace) { + return LinearSearchConnectionSelector.factory(linearSearchSpace) + .buildConnectionSelector("resource"); } @Test @@ -37,7 +37,7 @@ void selectsHosts() { // Ensure we can successfully select hosts for most sized pools for (int i = 1; i < 10; i++) { List connections = makeConnections(i); - ConnectionPoolStrategy strategy = strategy(5); + ConnectionSelector strategy = strategy(5); assertEquals(connections.get(0), strategy.select(connections, c -> true)); } } @@ -45,7 +45,7 @@ void selectsHosts() { @Test void picksHostsLinearlyUpToLinearSearchSpace() { List connections = makeConnections(10); - ConnectionPoolStrategy strategy = strategy(10); + ConnectionSelector strategy = strategy(10); Set selected = new HashSet<>(); for (int i = 0; i < 10; i++) { TestLoadBalancedConnection cxn = strategy.select(connections, c -> !selected.contains(c)); @@ -57,7 +57,7 @@ void picksHostsLinearlyUpToLinearSearchSpace() { @Test void canRandomlySearchAfterLinearSpace() { List connections = makeConnections(5); - ConnectionPoolStrategy strategy = strategy(1); + ConnectionSelector strategy = strategy(1); for (int i = 0; i < 100; i++) { assertNotNull(strategy.select(connections, c -> c != connections.get(0))); } diff --git a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategyTest.java b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionSelectorTest.java similarity index 83% rename from servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategyTest.java rename to servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionSelectorTest.java index 7abcb6e6ba..e60963fbf6 100644 --- a/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionPoolStrategyTest.java +++ b/servicetalk-loadbalancer-experimental/src/test/java/io/servicetalk/loadbalancer/P2CConnectionSelectorTest.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.function.Predicate; -import static io.servicetalk.loadbalancer.ConnectionPoolStrategyHelpers.makeConnections; +import static io.servicetalk.loadbalancer.ConnectionSelectorHelpers.makeConnections; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasItem; @@ -32,11 +32,11 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.when; -class P2CConnectionPoolStrategyTest { +class P2CConnectionSelectorTest { - private static ConnectionPoolStrategy strategy() { - return P2CConnectionPoolStrategy.factory(5, 5, false) - .buildStrategy("resource"); + private static ConnectionSelector strategy() { + return P2CConnectionSelector.factory(5, 5, false) + .buildConnectionSelector("resource"); } @Test @@ -44,7 +44,7 @@ void selectsHosts() { // Ensure we can successfully select hosts for most sized pools for (int i = 1; i < 10; i++) { List connections = makeConnections(i); - ConnectionPoolStrategy strategy = strategy(); + ConnectionSelector strategy = strategy(); assertNotNull(strategy.select(connections, c -> true)); } } @@ -52,7 +52,7 @@ void selectsHosts() { @Test void prefersCorePool() { List connections = makeConnections(10); - ConnectionPoolStrategy strategy = strategy(); + ConnectionSelector strategy = strategy(); Set selected = new HashSet<>(); for (int i = 0; i < 100; i++) { selected.add(strategy.select(connections, c -> true)); @@ -70,7 +70,7 @@ void prefersCorePool() { @Test void spillsIntoOverflow() { List connections = makeConnections(6); - ConnectionPoolStrategy strategy = strategy(); + ConnectionSelector strategy = strategy(); Set corePoolCxns = new HashSet<>(); for (int i = 0; i < 5; i++) { corePoolCxns.add(connections.get(i)); @@ -82,7 +82,7 @@ void spillsIntoOverflow() { @Test void prefersHigherScoringHosts() { List connections = makeConnections(2); - ConnectionPoolStrategy strategy = strategy(); + ConnectionSelector strategy = strategy(); // We should always get connection at index 1 becuase it has the higher score. when(connections.get(0).score()).thenReturn(0); when(connections.get(1).score()).thenReturn(1); @@ -95,7 +95,7 @@ void prefersHigherScoringHosts() { @Test void willSelectLowerScoringConnectionIfHigherScoredConnectionCantBeSelected() { List connections = makeConnections(2); - ConnectionPoolStrategy strategy = strategy(); + ConnectionSelector strategy = strategy(); // We should always get connection at index 1 becuase it has the higher score. when(connections.get(0).score()).thenReturn(0); when(connections.get(1).score()).thenReturn(1);