diff --git a/core/src/main/java/io/grpc/Internal.java b/core/src/main/java/io/grpc/Internal.java index e4cb1a46d8..479c1b16df 100644 --- a/core/src/main/java/io/grpc/Internal.java +++ b/core/src/main/java/io/grpc/Internal.java @@ -41,7 +41,7 @@ import java.lang.annotation.Target; * Annotates a program element (class, method, package etc) which is internal to gRPC, not part of * the public API, and should not be used by users of gRPC. * - *
However, if you want to implement a custom {@link LoadBalancer2}, an alternative transport, or + *
However, if you want to implement a custom {@link LoadBalancer}, an alternative transport, or * anything else that will be wired into gRPC library, you may use the internal parts. Please * consult the gRPC team first, because internal APIs don't have the same API stability guarantee as * the public APIs do. diff --git a/core/src/main/java/io/grpc/LoadBalancer.java b/core/src/main/java/io/grpc/LoadBalancer.java new file mode 100644 index 0000000000..1db9d3646a --- /dev/null +++ b/core/src/main/java/io/grpc/LoadBalancer.java @@ -0,0 +1,414 @@ +/* + * Copyright 2016, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc; + +import com.google.common.base.Preconditions; +import java.util.List; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.NotThreadSafe; +import javax.annotation.concurrent.ThreadSafe; + +/** + * A pluggable component that receives resolved addresses from {@link NameResolver} and provides the + * channel a usable subchannel when asked. + * + *
A LoadBalancer typically implements three interfaces: + *
{@link Helper Helper} is implemented by gRPC library and provided to {@link Factory + * Factory}. It provides functionalities that a {@code LoadBalancer} implementation would typically + * need. + * + *
Channel Executor is an internal executor of the channel, which is used to serialize all the + * callback methods on the {@link LoadBalancer} interface, thus the balancer implementation doesn't + * need to worry about synchronization among them. However, the actual thread of the Channel + * Executor is typically the network thread, thus the following rules must be followed to prevent + * blocking or even dead-locking in a network + * + *
{@link Helper#runSerialized Helper.runSerialized()} allows you to schedule a task to be run in + * the Channel Executor. + * + *
A {@link LoadBalancer} keeps states like the latest addresses from NameResolver, the + * Subchannel(s) and their latest connectivity states. These states are mutated within the Channel + * Executor. + * + *
A typical {@link SubchannelPicker SubchannelPicker} holds a snapshot of these states. It may + * have its own states, e.g., a picker from a round-robin load-balancer may keep a pointer to the + * next Subchannel, which are typically mutated by multiple threads. The picker should only mutate + * its own state, and should not mutate or re-acquire the states of the LoadBalancer. This way the + * picker only needs to synchronize its own states, which is typically trivial to implement. + * + *
When the LoadBalancer states changes, e.g., Subchannels has become or stopped being READY, and + * we want subsequent RPCs to use the latest list of READY Subchannels, LoadBalancer would create + * a new picker, which holds a snapshot of the latest Subchannel list. Refer to the javadoc of + * {@link #handleSubchannelState handleSubchannelState()} how to do this properly. + * + *
No synchronization should be necessary between LoadBalancer and its pickers if you follow + * the pattern above. It may be possible to implement in a different way, but that would usually + * result in more complicated threading. + */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") +@NotThreadSafe +public abstract class LoadBalancer { + /** + * Handles newly resolved server groups and metadata attributes from name resolution system. + * {@code servers} contained in {@link ResolvedServerInfoGroup} should be considered equivalent + * but may be flattened into a single list if needed. + * + *
Implementations should not modify the given {@code servers}.
+ *
+ * @param servers the resolved server addresses, never empty.
+ * @param attributes extra metadata from naming system.
+ */
+ public abstract void handleResolvedAddresses(
+ List The initial state of a Subchannel is IDLE. You won't get a notification for the initial IDLE
+ * state.
+ *
+ * If the new state is not SHUTDOWN, this method should create a new picker and call {@link
+ * Helper#updatePicker Helper.updatePicker()}. Failing to do so may result in unnecessary delays
+ * of RPCs. Please refer to {@link PickResult#withSubchannel PickResult.withSubchannel()}'s
+ * javadoc for more information.
+ *
+ * SHUTDOWN can only happen in two cases. One is that LoadBalancer called {@link
+ * Subchannel#shutdown} earlier, thus it should have already discarded this Subchannel. The other
+ * is that Channel is doing a {@link ManagedChannel#shutdownNow forced shutdown} or has already
+ * terminated, thus there won't be further requests to LoadBalancer. Therefore, SHUTDOWN can be
+ * safely ignored.
+ *
+ * @param subchannel the involved Subchannel
+ * @param stateInfo the new state
+ */
+ public abstract void handleSubchannelState(
+ Subchannel subchannel, ConnectivityStateInfo stateInfo);
+
+ /**
+ * The channel asks the load-balancer to shutdown. No more callbacks will be called after this
+ * method. The implementation should shutdown all Subchannels and OOB channels, and do any other
+ * cleanup as necessary.
+ */
+ public abstract void shutdown();
+
+ /**
+ * The main balancing logic. It must be thread-safe. Typically it should only
+ * synchronize on its own state, and avoid synchronizing with the LoadBalancer's state.
+ */
+ @ThreadSafe
+ public abstract static class SubchannelPicker {
+ /**
+ * Make a balancing decision for a new RPC.
+ *
+ * @param affinity the affinity attributes provided via {@link CallOptions#withAffinity}
+ * @param headers the headers container of the RPC. It can be mutated within this method.
+ */
+ public abstract PickResult pickSubchannel(Attributes affinity, Metadata headers);
+ }
+
+ /**
+ * A balancing decision made by {@link SubchannelPicker SubchannelPicker} for an RPC.
+ *
+ * The outcome of the decision will be one of the following:
+ * Only Subchannels returned by {@link Helper#createSubchannel Helper.createSubchannel()}
+ * will work. DO NOT try to use your own implementations of Subchannels, as they won't work.
+ *
+ * When the RPC tries to use the return Subchannel, which is briefly after this method
+ * returns, the state of the Subchannel will decide where the RPC would go:
+ *
+ * All buffered RPCs will stay buffered until the next call of {@link
+ * Helper#updatePicker Helper.updatePicker()}, which will trigger a new picking process.
+ *
+ * Note that Subchannel's state may change at the same time the picker is making the
+ * decision, which means the decision may be made with (to-be) outdated information. For
+ * example, a picker may return a Subchannel known to be READY, but it has become IDLE when is
+ * about to be used by the RPC, which makes the RPC to be buffered. The LoadBalancer will soon
+ * learn about the Subchannels' transition from READY to IDLE, create a new picker and allow the
+ * RPC to use another READY transport if there is any.
+ *
+ * You will want to avoid running into a situation where there are READY Subchannels out
+ * there but some RPCs are still buffered for longer than a brief time.
+ * In order to prevent unnecessary delay of RPCs, the rules of thumb are:
+ * The LoadBalancer is responsible for closing unused Subchannels, and closing all
+ * Subchannels within {@link #shutdown}.
+ */
+ public abstract Subchannel createSubchannel(EquivalentAddressGroup addrs, Attributes attrs);
+
+ /**
+ * Out-of-band channel for LoadBalancer’s own RPC needs, e.g., talking to an external
+ * load-balancer service.
+ *
+ * The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
+ * channels within {@link #shutdown}.
+ */
+ public abstract ManagedChannel createOobChannel(
+ EquivalentAddressGroup eag, String authority);
+
+ /**
+ * Set a new picker to the channel.
+ *
+ * When a new picker is provided via {@code updatePicker()}, the channel will apply the
+ * picker on all buffered RPCs, by calling {@link SubchannelPicker#pickSubchannel
+ * SubchannelPicker.pickSubchannel()}.
+ *
+ * The channel will hold the picker and use it for all RPCs, until {@code updatePicker()} is
+ * called again and a new picker replaces the old one. If {@code updatePicker()} has never been
+ * called, the channel will buffer all RPCs until a picker is provided.
+ */
+ public abstract void updatePicker(SubchannelPicker picker);
+
+ /**
+ * Schedule a task to be run in the Channel Executor, which serializes the task with the
+ * callback methods on the {@link LoadBalancer} interface.
+ */
+ public abstract void runSerialized(Runnable task);
+
+ /**
+ * Returns the NameResolver of the channel.
+ */
+ public abstract NameResolver.Factory getNameResolverFactory();
+
+ /**
+ * Returns the authority string of the channel, which is derived from the DNS-style target name.
+ */
+ public abstract String getAuthority();
+ }
+
+ /**
+ * A logical connection to a server, or a group of equivalent servers represented by an {@link
+ * EquivalentAddressGroup}.
+ *
+ * It maintains at most one physical connection (aka transport) for sending new RPCs, while
+ * also keeps track of previous transports that has been shut down but not terminated yet.
+ *
+ * If there isn't an active transport yet, and an RPC is assigned to the Subchannel, it will
+ * create a new transport. It won't actively create transports otherwise. {@link
+ * #requestConnection requestConnection()} can be used to ask Subchannel to create a transport if
+ * there isn't any.
+ */
+ @ThreadSafe
+ public abstract static class Subchannel {
+ /**
+ * Shuts down the Subchannel. After this method is called, this Subchannel should no longer
+ * be returned by the latest {@link SubchannelPicker picker}, and can be safely discarded.
+ */
+ public abstract void shutdown();
+
+ /**
+ * Asks the Subchannel to create a connection (aka transport), if there isn't an active one.
+ */
+ public abstract void requestConnection();
+
+ /**
+ * Returns the addresses that this Subchannel is bound to.
+ */
+ public abstract EquivalentAddressGroup getAddresses();
+
+ /**
+ * The same attributes passed to {@link Helper#createSubchannel Helper.createSubchannel()}.
+ * LoadBalancer can use it to attach additional information here, e.g., the shard this
+ * Subchannel belongs to.
+ */
+ public abstract Attributes getAttributes();
+ }
+
+ @ThreadSafe
+ public abstract static class Factory {
+ /**
+ * Creates a {@link LoadBalancer} that will be used inside a channel.
+ */
+ public abstract LoadBalancer newLoadBalancer(Helper helper);
+ }
+}
diff --git a/core/src/main/java/io/grpc/LoadBalancer2.java b/core/src/main/java/io/grpc/LoadBalancer2.java
index a4772df46d..fe0b0f5e1e 100644
--- a/core/src/main/java/io/grpc/LoadBalancer2.java
+++ b/core/src/main/java/io/grpc/LoadBalancer2.java
@@ -31,390 +31,13 @@
package io.grpc;
-import com.google.common.base.Preconditions;
-import java.util.List;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.NotThreadSafe;
-import javax.annotation.concurrent.ThreadSafe;
-
/**
- * A pluggable component that receives resolved addresses from {@link NameResolver} and provides the
- * channel a usable subchannel when asked. This is the new interface that will replace {@link
- * LoadBalancer2}.
+ * An alias for {@link LoadBalancer}.
*
- * IMPORTANT NOTICE FOR IMPLEMENTORS: The name of this class is temporary. It
- * will be renamed to {@code LoadBalancer} eventually. Make sure you have read through #2656 to understand the
- * transition path.
- *
- * A LoadBalancer typically implements three interfaces:
- * {@link Helper Helper} is implemented by gRPC library and provided to {@link Factory
- * Factory}. It provides functionalities that a {@code LoadBalancer2} implementation would typically
- * need.
- *
- * Channel Executor is an internal executor of the channel, which is used to serialize all the
- * callback methods on the {@link LoadBalancer2} interface, thus the balancer implementation doesn't
- * need to worry about synchronization among them. However, the actual thread of the Channel
- * Executor is typically the network thread, thus the following rules must be followed to prevent
- * blocking or even dead-locking in a network
- *
- * {@link Helper#runSerialized Helper.runSerialized()} allows you to schedule a task to be run in
- * the Channel Executor.
- *
- * A {@link LoadBalancer2} keeps states like the latest addresses from NameResolver, the
- * Subchannel(s) and their latest connectivity states. These states are mutated within the Channel
- * Executor.
- *
- * A typical {@link SubchannelPicker SubchannelPicker} holds a snapshot of these states. It may
- * have its own states, e.g., a picker from a round-robin load-balancer may keep a pointer to the
- * next Subchannel, which are typically mutated by multiple threads. The picker should only mutate
- * its own state, and should not mutate or re-acquire the states of the LoadBalancer. This way the
- * picker only needs to synchronize its own states, which is typically trivial to implement.
- *
- * When the LoadBalancer states changes, e.g., Subchannels has become or stopped being READY, and
- * we want subsequent RPCs to use the latest list of READY Subchannels, LoadBalancer would create
- * a new picker, which holds a snapshot of the latest Subchannel list. Refer to the javadoc of
- * {@link #handleSubchannelState handleSubchannelState()} how to do this properly.
- *
- * No synchronization should be necessary between LoadBalancer and its pickers if you follow
- * the pattern above. It may be possible to implement in a different way, but that would usually
- * result in more complicated threading.
+ * @deprecated this is going to be deleted in the next minor release. Use {@link LoadBalancer}
+ * instead.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
-@NotThreadSafe
-public abstract class LoadBalancer2 {
- /**
- * Handles newly resolved server groups and metadata attributes from name resolution system.
- * {@code servers} contained in {@link ResolvedServerInfoGroup} should be considered equivalent
- * but may be flattened into a single list if needed.
- *
- * Implementations should not modify the given {@code servers}.
- *
- * @param servers the resolved server addresses, never empty.
- * @param attributes extra metadata from naming system.
- */
- public abstract void handleResolvedAddresses(
- List The initial state of a Subchannel is IDLE. You won't get a notification for the initial IDLE
- * state.
- *
- * If the new state is not SHUTDOWN, this method should create a new picker and call {@link
- * Helper#updatePicker Helper.updatePicker()}. Failing to do so may result in unnecessary delays
- * of RPCs. Please refer to {@link PickResult#withSubchannel PickResult.withSubchannel()}'s
- * javadoc for more information.
- *
- * SHUTDOWN can only happen in two cases. One is that LoadBalancer called {@link
- * Subchannel#shutdown} earlier, thus it should have already discarded this Subchannel. The other
- * is that Channel is doing a {@link ManagedChannel#shutdownNow forced shutdown} or has already
- * terminated, thus there won't be further requests to LoadBalancer. Therefore, SHUTDOWN can be
- * safely ignored.
- *
- * @param subchannel the involved Subchannel
- * @param stateInfo the new state
- */
- public abstract void handleSubchannelState(
- Subchannel subchannel, ConnectivityStateInfo stateInfo);
-
- /**
- * The channel asks the load-balancer to shutdown. No more callbacks will be called after this
- * method. The implementation should shutdown all Subchannels and OOB channels, and do any other
- * cleanup as necessary.
- */
- public abstract void shutdown();
-
- /**
- * The main balancing logic. It must be thread-safe. Typically it should only
- * synchronize on its own state, and avoid synchronizing with the LoadBalancer's state.
- */
- @ThreadSafe
- public abstract static class SubchannelPicker {
- /**
- * Make a balancing decision for a new RPC.
- *
- * @param affinity the affinity attributes provided via {@link CallOptions#withAffinity}
- * @param headers the headers container of the RPC. It can be mutated within this method.
- */
- public abstract PickResult pickSubchannel(Attributes affinity, Metadata headers);
- }
-
- /**
- * A balancing decision made by {@link SubchannelPicker SubchannelPicker} for an RPC.
- *
- * The outcome of the decision will be one of the following:
- * Only Subchannels returned by {@link Helper#createSubchannel Helper.createSubchannel()}
- * will work. DO NOT try to use your own implementations of Subchannels, as they won't work.
- *
- * When the RPC tries to use the return Subchannel, which is briefly after this method
- * returns, the state of the Subchannel will decide where the RPC would go:
- *
- * All buffered RPCs will stay buffered until the next call of {@link
- * Helper#updatePicker Helper.updatePicker()}, which will trigger a new picking process.
- *
- * Note that Subchannel's state may change at the same time the picker is making the
- * decision, which means the decision may be made with (to-be) outdated information. For
- * example, a picker may return a Subchannel known to be READY, but it has become IDLE when is
- * about to be used by the RPC, which makes the RPC to be buffered. The LoadBalancer will soon
- * learn about the Subchannels' transition from READY to IDLE, create a new picker and allow the
- * RPC to use another READY transport if there is any.
- *
- * You will want to avoid running into a situation where there are READY Subchannels out
- * there but some RPCs are still buffered for longer than a brief time.
- * In order to prevent unnecessary delay of RPCs, the rules of thumb are:
- * The LoadBalancer is responsible for closing unused Subchannels, and closing all
- * Subchannels within {@link #shutdown}.
- */
- public abstract Subchannel createSubchannel(EquivalentAddressGroup addrs, Attributes attrs);
-
- /**
- * Out-of-band channel for LoadBalancer’s own RPC needs, e.g., talking to an external
- * load-balancer service.
- *
- * The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
- * channels within {@link #shutdown}.
- */
- public abstract ManagedChannel createOobChannel(
- EquivalentAddressGroup eag, String authority);
-
- /**
- * Set a new picker to the channel.
- *
- * When a new picker is provided via {@code updatePicker()}, the channel will apply the
- * picker on all buffered RPCs, by calling {@link SubchannelPicker#pickSubchannel
- * SubchannelPicker.pickSubchannel()}.
- *
- * The channel will hold the picker and use it for all RPCs, until {@code updatePicker()} is
- * called again and a new picker replaces the old one. If {@code updatePicker()} has never been
- * called, the channel will buffer all RPCs until a picker is provided.
- */
- public abstract void updatePicker(SubchannelPicker picker);
-
- /**
- * Schedule a task to be run in the Channel Executor, which serializes the task with the
- * callback methods on the {@link LoadBalancer2} interface.
- */
- public abstract void runSerialized(Runnable task);
-
- /**
- * Returns the NameResolver of the channel.
- */
- public abstract NameResolver.Factory getNameResolverFactory();
-
- /**
- * Returns the authority string of the channel, which is derived from the DNS-style target name.
- */
- public abstract String getAuthority();
- }
-
- /**
- * A logical connection to a server, or a group of equivalent servers represented by an {@link
- * EquivalentAddressGroup}.
- *
- * It maintains at most one physical connection (aka transport) for sending new RPCs, while
- * also keeps track of previous transports that has been shut down but not terminated yet.
- *
- * If there isn't an active transport yet, and an RPC is assigned to the Subchannel, it will
- * create a new transport. It won't actively create transports otherwise. {@link
- * #requestConnection requestConnection()} can be used to ask Subchannel to create a transport if
- * there isn't any.
- */
- @ThreadSafe
- public abstract static class Subchannel {
- /**
- * Shuts down the Subchannel. After this method is called, this Subchannel should no longer
- * be returned by the latest {@link SubchannelPicker picker}, and can be safely discarded.
- */
- public abstract void shutdown();
-
- /**
- * Asks the Subchannel to create a connection (aka transport), if there isn't an active one.
- */
- public abstract void requestConnection();
-
- /**
- * Returns the addresses that this Subchannel is bound to.
- */
- public abstract EquivalentAddressGroup getAddresses();
-
- /**
- * The same attributes passed to {@link Helper#createSubchannel Helper.createSubchannel()}.
- * LoadBalancer can use it to attach additional information here, e.g., the shard this
- * Subchannel belongs to.
- */
- public abstract Attributes getAttributes();
- }
-
- @ThreadSafe
- public abstract static class Factory {
- /**
- * Creates a {@link LoadBalancer2} that will be used inside a channel.
- */
- public abstract LoadBalancer2 newLoadBalancer(Helper helper);
- }
+@Deprecated
+public abstract class LoadBalancer2 extends LoadBalancer {
}
diff --git a/core/src/main/java/io/grpc/ManagedChannelBuilder.java b/core/src/main/java/io/grpc/ManagedChannelBuilder.java
index eb6734c620..bd17459857 100644
--- a/core/src/main/java/io/grpc/ManagedChannelBuilder.java
+++ b/core/src/main/java/io/grpc/ManagedChannelBuilder.java
@@ -155,9 +155,9 @@ public abstract class ManagedChannelBuilder If this method is not called, the builder will use {@link PickFirstBalancerFactory2}
+ * If this method is not called, the builder will use {@link PickFirstBalancerFactory}
* for the channel.
*
* Calling this will make the channel to run the LBv2 code path. See >
* this method will throw.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
- public T loadBalancerFactory(LoadBalancer2.Factory loadBalancerFactory) {
- throw new UnsupportedOperationException("Not implemented by " + this.getClass().getName());
- }
+ public abstract T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory);
/**
* Set the decompression registry for use in the channel. This is an advanced API call and
diff --git a/core/src/main/java/io/grpc/PickFirstBalancerFactory2.java b/core/src/main/java/io/grpc/PickFirstBalancerFactory.java
similarity index 78%
rename from core/src/main/java/io/grpc/PickFirstBalancerFactory2.java
rename to core/src/main/java/io/grpc/PickFirstBalancerFactory.java
index 2ef0d44020..0c46cdde6a 100644
--- a/core/src/main/java/io/grpc/PickFirstBalancerFactory2.java
+++ b/core/src/main/java/io/grpc/PickFirstBalancerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016, Google Inc. All rights reserved.
+ * Copyright 2015, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,6 +31,7 @@
package io.grpc;
+import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.ConnectivityState.SHUTDOWN;
import com.google.common.annotations.VisibleForTesting;
@@ -39,44 +40,39 @@ import java.util.ArrayList;
import java.util.List;
/**
- * A {@link LoadBalancer2} that provides no load balancing mechanism over the
+ * A {@link LoadBalancer} that provides no load balancing mechanism over the
* addresses from the {@link NameResolver}. The channel's default behavior
* (currently pick-first) is used for all addresses found.
- *
- * TECHNICAL PREVIEW: The name of this class is temporary. It will be renamed to
- * {@code PickFirstBalancerFactory} during the transition to LBv2. You should use it only if you want to experiment the
- * LBv2 code path.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
-public final class PickFirstBalancerFactory2 extends LoadBalancer2.Factory {
+public final class PickFirstBalancerFactory extends LoadBalancer.Factory {
- private static final PickFirstBalancerFactory2 INSTANCE = new PickFirstBalancerFactory2();
+ private static final PickFirstBalancerFactory INSTANCE = new PickFirstBalancerFactory();
- private PickFirstBalancerFactory2() {
+ private PickFirstBalancerFactory() {
}
- public static PickFirstBalancerFactory2 getInstance() {
+ public static PickFirstBalancerFactory getInstance() {
return INSTANCE;
}
@Override
- public LoadBalancer2 newLoadBalancer(LoadBalancer2.Helper helper) {
+ public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper) {
return new PickFirstBalancer(helper);
}
@VisibleForTesting
- static class PickFirstBalancer extends LoadBalancer2 {
+ static final class PickFirstBalancer extends LoadBalancer {
private final Helper helper;
private Subchannel subchannel;
- public PickFirstBalancer(Helper helper) {
- this.helper = helper;
+ PickFirstBalancer(Helper helper) {
+ this.helper = checkNotNull(helper, "helper");
}
@Override
- public void handleResolvedAddresses(List Tasks are queued until {@link #drain} is called. Tasks are guaranteed to be run in the same
* order as they are submitted.
diff --git a/core/src/main/java/io/grpc/internal/DelayedClientTransport2.java b/core/src/main/java/io/grpc/internal/DelayedClientTransport.java
similarity index 95%
rename from core/src/main/java/io/grpc/internal/DelayedClientTransport2.java
rename to core/src/main/java/io/grpc/internal/DelayedClientTransport.java
index 3318db861c..aa91dae136 100644
--- a/core/src/main/java/io/grpc/internal/DelayedClientTransport2.java
+++ b/core/src/main/java/io/grpc/internal/DelayedClientTransport.java
@@ -34,8 +34,8 @@ package io.grpc.internal;
import com.google.common.annotations.VisibleForTesting;
import io.grpc.CallOptions;
import io.grpc.Context;
-import io.grpc.LoadBalancer2.PickResult;
-import io.grpc.LoadBalancer2.SubchannelPicker;
+import io.grpc.LoadBalancer.PickResult;
+import io.grpc.LoadBalancer.SubchannelPicker;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.Status;
@@ -55,7 +55,7 @@ import javax.annotation.concurrent.GuardedBy;
* for that stream, at which point the ownership of the stream is transferred to the real transport,
* thus the delayed transport stops owning the stream.
*/
-final class DelayedClientTransport2 implements ManagedClientTransport {
+final class DelayedClientTransport implements ManagedClientTransport {
private final LogId lodId = LogId.allocate(getClass().getName());
private final Object lock = new Object();
@@ -96,7 +96,7 @@ final class DelayedClientTransport2 implements ManagedClientTransport {
* @param channelExecutor all listener callbacks of the delayed transport will be run from this
* ChannelExecutor.
*/
- DelayedClientTransport2(Executor defaultAppExecutor, ChannelExecutor channelExecutor) {
+ DelayedClientTransport(Executor defaultAppExecutor, ChannelExecutor channelExecutor) {
this.defaultAppExecutor = defaultAppExecutor;
this.channelExecutor = channelExecutor;
}
@@ -188,13 +188,16 @@ final class DelayedClientTransport2 implements ManagedClientTransport {
return newStream(method, headers, CallOptions.DEFAULT, StatsTraceContext.NOOP);
}
- // Caller must call channelExecutor.drain() outside of lock because this method may schedule
- // tasks on channelExecutor
+ /**
+ * Caller must call {@code channelExecutor.drain()} outside of lock because this method may
+ * schedule tasks on channelExecutor.
+ */
@GuardedBy("lock")
- private PendingStream createPendingStream(MethodDescriptor, ?> method, Metadata headers,
- CallOptions callOptions, StatsTraceContext statsTraceCtx) {
- PendingStream pendingStream = new PendingStream(method, headers, callOptions,
- statsTraceCtx);
+ private PendingStream createPendingStream(
+ MethodDescriptor, ?> method, Metadata headers, CallOptions callOptions,
+ StatsTraceContext statsTraceCtx) {
+ PendingStream pendingStream =
+ new PendingStream(method, headers, callOptions, statsTraceCtx);
pendingStreams.add(pendingStream);
if (pendingStreams.size() == 1) {
channelExecutor.executeLater(reportTransportInUse);
diff --git a/core/src/main/java/io/grpc/internal/GrpcUtil.java b/core/src/main/java/io/grpc/internal/GrpcUtil.java
index c532fe2c6d..385551e757 100644
--- a/core/src/main/java/io/grpc/internal/GrpcUtil.java
+++ b/core/src/main/java/io/grpc/internal/GrpcUtil.java
@@ -40,8 +40,8 @@ import com.google.common.base.Stopwatch;
import com.google.common.base.Supplier;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import io.grpc.LoadBalancer2.PickResult;
-import io.grpc.LoadBalancer2.Subchannel;
+import io.grpc.LoadBalancer.PickResult;
+import io.grpc.LoadBalancer.Subchannel;
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.internal.SharedResourceHolder.Resource;
diff --git a/core/src/main/java/io/grpc/internal/InUseStateAggregator2.java b/core/src/main/java/io/grpc/internal/InUseStateAggregator.java
similarity index 98%
rename from core/src/main/java/io/grpc/internal/InUseStateAggregator2.java
rename to core/src/main/java/io/grpc/internal/InUseStateAggregator.java
index 6333f36097..9668e278df 100644
--- a/core/src/main/java/io/grpc/internal/InUseStateAggregator2.java
+++ b/core/src/main/java/io/grpc/internal/InUseStateAggregator.java
@@ -38,7 +38,7 @@ import javax.annotation.concurrent.NotThreadSafe;
* Aggregates the in-use state of a set of objects.
*/
@NotThreadSafe
-abstract class InUseStateAggregator2
+ *
+ */
+ @Immutable
+ public static final class PickResult {
+ private static final PickResult NO_RESULT = new PickResult(null, Status.OK);
+
+ @Nullable private final Subchannel subchannel;
+ // An error to be propagated to the application if subchannel == null
+ // Or OK if there is no error.
+ // subchannel being null and error being OK means RPC needs to wait
+ private final Status status;
+
+ private PickResult(Subchannel subchannel, Status status) {
+ this.subchannel = subchannel;
+ this.status = Preconditions.checkNotNull(status, "status");
+ }
+
+ /**
+ * A decision to proceed the RPC on a Subchannel.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ public static PickResult withSubchannel(Subchannel subchannel) {
+ return new PickResult(Preconditions.checkNotNull(subchannel, "subchannel"), Status.OK);
+ }
+
+ /**
+ * A decision to report a connectivity error to the RPC. If the RPC is {@link
+ * CallOptions#withWaitForReady wait-for-ready}, it will stay buffered. Otherwise, it will fail
+ * with the given error.
+ *
+ * @param error the error status. Must not be OK.
+ */
+ public static PickResult withError(Status error) {
+ Preconditions.checkArgument(!error.isOk(), "error status shouldn't be OK");
+ return new PickResult(null, error);
+ }
+
+ /**
+ * No decision could be made. The RPC will stay buffered.
+ */
+ public static PickResult withNoResult() {
+ return NO_RESULT;
+ }
+
+ /**
+ * The Subchannel if this result was created by {@link #withSubchannel withSubchannel()}, or
+ * null otherwise.
+ */
+ @Nullable
+ public Subchannel getSubchannel() {
+ return subchannel;
+ }
+
+ /**
+ * The status associated with this result. Non-{@code OK} if created with {@link #withError
+ * withError}, or {@code OK} otherwise.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ @Override
+ public String toString() {
+ return "[subchannel=" + subchannel + " status=" + status + "]";
+ }
+ }
+
+ /**
+ * Provides essentials for LoadBalancer implementations.
+ */
+ @ThreadSafe
+ public abstract static class Helper {
+ /**
+ * Creates a Subchannel, which is a logical connection to the given group of addresses which are
+ * considered equivalent. The {@code attrs} are custom attributes associated with this
+ * Subchannel, and can be accessed later through {@link Subchannel#getAttributes
+ * Subchannel.getAttributes()}.
+ *
+ *
+ *
Overview
- *
- *
- *
- *
- * Channel Executor
- *
- *
- *
- *
- *
- * The canonical implementation pattern
- *
- *
- *
- */
- @Immutable
- public static final class PickResult {
- private static final PickResult NO_RESULT = new PickResult(null, Status.OK);
-
- @Nullable private final Subchannel subchannel;
- // An error to be propagated to the application if subchannel == null
- // Or OK if there is no error.
- // subchannel being null and error being OK means RPC needs to wait
- private final Status status;
-
- private PickResult(Subchannel subchannel, Status status) {
- this.subchannel = subchannel;
- this.status = Preconditions.checkNotNull(status, "status");
- }
-
- /**
- * A decision to proceed the RPC on a Subchannel.
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
- public static PickResult withSubchannel(Subchannel subchannel) {
- return new PickResult(Preconditions.checkNotNull(subchannel, "subchannel"), Status.OK);
- }
-
- /**
- * A decision to report a connectivity error to the RPC. If the RPC is {@link
- * CallOptions#withWaitForReady wait-for-ready}, it will stay buffered. Otherwise, it will fail
- * with the given error.
- *
- * @param error the error status. Must not be OK.
- */
- public static PickResult withError(Status error) {
- Preconditions.checkArgument(!error.isOk(), "error status shouldn't be OK");
- return new PickResult(null, error);
- }
-
- /**
- * No decision could be made. The RPC will stay buffered.
- */
- public static PickResult withNoResult() {
- return NO_RESULT;
- }
-
- /**
- * The Subchannel if this result was created by {@link #withSubchannel withSubchannel()}, or
- * null otherwise.
- */
- @Nullable
- public Subchannel getSubchannel() {
- return subchannel;
- }
-
- /**
- * The status associated with this result. Non-{@code OK} if created with {@link #withError
- * withError}, or {@code OK} otherwise.
- */
- public Status getStatus() {
- return status;
- }
-
- @Override
- public String toString() {
- return "[subchannel=" + subchannel + " status=" + status + "]";
- }
- }
-
- /**
- * Provides essentials for LoadBalancer implementations.
- */
- @ThreadSafe
- public abstract static class Helper {
- /**
- * Creates a Subchannel, which is a logical connection to the given group of addresses which are
- * considered equivalent. The {@code attrs} are custom attributes associated with this
- * Subchannel, and can be accessed later through {@link Subchannel#getAttributes
- * Subchannel.getAttributes()}.
- *
- *
- *