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. + * + *

Overview

+ * + *

A LoadBalancer typically implements three interfaces: + *

    + *
  1. {@link LoadBalancer} is the main interface. All methods on it are invoked sequentially + * from the Channel Executor. It receives the results from the {@link NameResolver}, updates + * of subchannels' connectivity states, and the channel's request for the LoadBalancer to + * shutdown.
  2. + *
  3. {@link SubchannelPicker SubchannelPicker} does the actual load-balancing work. It selects + * a {@link Subchannel Subchannel} for each new RPC.
  4. + *
  5. {@link Factory Factory} creates a new {@link LoadBalancer} instance. + *
+ * + *

{@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

+ * + *

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 + * + *

    + * + *
  1. Never block in Channel Executor. The callback methods must return + * quickly. Examples or work that must be avoided: CPU-intensive calculation, waiting on + * synchronization primitives, blocking I/O, blocking RPCs, etc.
  2. + * + *
  3. Avoid calling into other components with lock held. Channel Executor may + * run callbacks under a lock, e.g., the transport lock of OkHttp. If your LoadBalancer has a + * lock, holds the lock in a callback method (e.g., {@link #handleSubchannelState + * handleSubchannelState()}) while calling into another class that may involve locks, be cautious + * of deadlock. Generally you wouldn't need any locking in the LoadBalancer.
  4. + * + *
+ * + *

{@link Helper#runSerialized Helper.runSerialized()} allows you to schedule a task to be run in + * the Channel Executor. + * + *

The canonical implementation pattern

+ * + *

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 servers, Attributes attributes); + + /** + * Handles an error from the name resolution system. + * + * @param error a non-OK status + */ + public abstract void handleNameResolutionError(Status error); + + /** + * Handles a state change on a Subchannel. + * + *

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: + *

+ */ + @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. + * + *

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: + *

    + *
  1. The picker should only pick Subchannels that are known as READY or IDLE. Whether to + * pick IDLE Subchannels depends on whether you want Subchannels to connect on-demand or + * actively: + *
  2. + *
  3. Always create a new picker and call {@link Helper#updatePicker Helper.updatePicker()} + * whenever {@link #handleSubchannelState handleSubchannelState()} is called, unless the + * new state is SHUTDOWN. See {@code handleSubchannelState}'s javadoc for more + * details.
  4. + *
+ */ + 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()}. + * + *

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. - * - *

Overview

- * - *

A LoadBalancer typically implements three interfaces: - *

    - *
  1. {@link LoadBalancer2} is the main interface. All methods on it are invoked sequentially - * from the Channel Executor. It receives the results from the {@link NameResolver}, updates - * of subchannels' connectivity states, and the channel's request for the LoadBalancer to - * shutdown.
  2. - *
  3. {@link SubchannelPicker SubchannelPicker} does the actual load-balancing work. It selects - * a {@link Subchannel Subchannel} for each new RPC.
  4. - *
  5. {@link Factory Factory} creates a new {@link LoadBalancer2} instance. - *
- * - *

{@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

- * - *

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 - * - *

    - * - *
  1. Never block in Channel Executor. The callback methods must return - * quickly. Examples or work that must be avoided: CPU-intensive calculation, waiting on - * synchronization primitives, blocking I/O, blocking RPCs, etc.
  2. - * - *
  3. Avoid calling into other components with lock held. Channel Executor may - * run callbacks under a lock, e.g., the transport lock of OkHttp. If your LoadBalancer has a - * lock, holds the lock in a callback method (e.g., {@link #handleSubchannelState - * handleSubchannelState()}) while calling into another class that may involve locks, be cautious - * of deadlock. Generally you wouldn't need any locking in the LoadBalancer.
  4. - * - *
- * - *

{@link Helper#runSerialized Helper.runSerialized()} allows you to schedule a task to be run in - * the Channel Executor. - * - *

The canonical implementation pattern

- * - *

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 servers, Attributes attributes); - - /** - * Handles an error from the name resolution system. - * - * @param error a non-OK status - */ - public abstract void handleNameResolutionError(Status error); - - /** - * Handles a state change on a Subchannel. - * - *

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: - *

- */ - @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. - * - *

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: - *

    - *
  1. The picker should only pick Subchannels that are known as READY or IDLE. Whether to - * pick IDLE Subchannels depends on whether you want Subchannels to connect on-demand or - * actively: - *
  2. - *
  3. Always create a new picker and call {@link Helper#updatePicker Helper.updatePicker()} - * whenever {@link #handleSubchannelState handleSubchannelState()} is called, unless the - * new state is SHUTDOWN. See {@code handleSubchannelState}'s javadoc for more - * details.
  4. - *
- */ - 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()}. - * - *

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> public abstract T nameResolverFactory(NameResolver.Factory resolverFactory); /** - * Provides a custom {@link LoadBalancer2.Factory} for the channel. + * Provides a custom {@link LoadBalancer.Factory} for the channel. * - *

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 servers, - Attributes attributes) { + public void handleResolvedAddresses( + List servers, Attributes attributes) { // Flatten servers list received from name resolver into single address group. This means that // as far as load balancer is concerned, there's virtually one single server with multiple // addresses so the connection will be created only for the first address (pick first). @@ -123,7 +119,7 @@ public final class PickFirstBalancerFactory2 extends LoadBalancer2.Factory { pickResult = PickResult.withError(stateInfo.getStatus()); break; default: - throw new IllegalStateException(); + throw new IllegalArgumentException("Unsupported state:" + currentState); } helper.updatePicker(new Picker(pickResult)); @@ -157,15 +153,15 @@ public final class PickFirstBalancerFactory2 extends LoadBalancer2.Factory { * received in constructor. */ @VisibleForTesting - static class Picker extends LoadBalancer2.SubchannelPicker { - private final LoadBalancer2.PickResult result; + static final class Picker extends LoadBalancer.SubchannelPicker { + private final LoadBalancer.PickResult result; - Picker(LoadBalancer2.PickResult result) { - this.result = result; + Picker(LoadBalancer.PickResult result) { + this.result = checkNotNull(result, "result"); } @Override - public LoadBalancer2.PickResult pickSubchannel(Attributes affinity, Metadata headers) { + public LoadBalancer.PickResult pickSubchannel(Attributes affinity, Metadata headers) { return result; } } diff --git a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java index 7c3ba426e3..a403e262e7 100644 --- a/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java +++ b/core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java @@ -43,12 +43,12 @@ import io.grpc.Attributes; import io.grpc.ClientInterceptor; import io.grpc.CompressorRegistry; import io.grpc.DecompressorRegistry; -import io.grpc.LoadBalancer2; +import io.grpc.LoadBalancer; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.NameResolver; import io.grpc.NameResolverProvider; -import io.grpc.PickFirstBalancerFactory2; +import io.grpc.PickFirstBalancerFactory; import io.grpc.ResolvedServerInfo; import io.grpc.ResolvedServerInfoGroup; import java.net.SocketAddress; @@ -108,7 +108,7 @@ public abstract class AbstractManagedChannelImplBuilder @Nullable private NameResolver.Factory nameResolverFactory; - private LoadBalancer2.Factory loadBalancerFactory; + private LoadBalancer.Factory loadBalancerFactory; @Nullable private DecompressorRegistry decompressorRegistry; @@ -193,9 +193,9 @@ public abstract class AbstractManagedChannelImplBuilder } @Override - public final T loadBalancerFactory(LoadBalancer2.Factory loadBalancerFactory) { + public final T loadBalancerFactory(LoadBalancer.Factory loadBalancerFactory) { Preconditions.checkState(directServerAddress == null, - "directServerAddress is set (%s), which forbids the use of LoadBalancerFactory", + "directServerAddress is set (%s), which forbids the use of LoadBalancer.Factory", directServerAddress); this.loadBalancerFactory = loadBalancerFactory; return thisT(); @@ -231,7 +231,7 @@ public abstract class AbstractManagedChannelImplBuilder // We convert to the largest unit to avoid overflow if (unit.toDays(value) >= IDLE_MODE_MAX_TIMEOUT_DAYS) { // This disables idle mode - this.idleTimeoutMillis = ManagedChannelImpl2.IDLE_TIMEOUT_MILLIS_DISABLE; + this.idleTimeoutMillis = ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE; } else { this.idleTimeoutMillis = Math.max(unit.toMillis(value), IDLE_MODE_MIN_TIMEOUT_MILLIS); } @@ -275,21 +275,25 @@ public abstract class AbstractManagedChannelImplBuilder // getResource(), then this shouldn't be a problem unless called on the UI thread. nameResolverFactory = NameResolverProvider.asFactory(); } - return new ManagedChannelImpl2( + return new ManagedChannelImpl( target, // TODO(carl-mastrangelo): Allow clients to pass this in new ExponentialBackoffPolicy.Provider(), nameResolverFactory, getNameResolverParams(), - firstNonNull(loadBalancerFactory, PickFirstBalancerFactory2.getInstance()), + firstNonNull(loadBalancerFactory, PickFirstBalancerFactory.getInstance()), transportFactory, firstNonNull(decompressorRegistry, DecompressorRegistry.getDefaultInstance()), firstNonNull(compressorRegistry, CompressorRegistry.getDefaultInstance()), SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE), getExecutorPool(executor), SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR), - GrpcUtil.STOPWATCH_SUPPLIER, idleTimeoutMillis, - userAgent, interceptors, firstNonNull(statsFactory, + GrpcUtil.STOPWATCH_SUPPLIER, + idleTimeoutMillis, + userAgent, + interceptors, + firstNonNull( + statsFactory, firstNonNull(Stats.getStatsContextFactory(), NoopStatsContextFactory.INSTANCE))); } diff --git a/core/src/main/java/io/grpc/internal/ChannelExecutor.java b/core/src/main/java/io/grpc/internal/ChannelExecutor.java index 3bf549d910..6ab8e3b1ff 100644 --- a/core/src/main/java/io/grpc/internal/ChannelExecutor.java +++ b/core/src/main/java/io/grpc/internal/ChannelExecutor.java @@ -42,7 +42,7 @@ import javax.annotation.concurrent.ThreadSafe; /** * The thread-less Channel Executor used to run the state mutation logic in {@link - * ManagedChannelImpl}, {@link InternalSubchannel} and {@link io.grpc.LoadBalancer2}s. + * ManagedChannelImpl}, {@link InternalSubchannel} and {@link io.grpc.LoadBalancer}s. * *

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 { +abstract class InUseStateAggregator { private final HashSet inUseObjects = new HashSet(); diff --git a/core/src/main/java/io/grpc/internal/InternalSubchannel.java b/core/src/main/java/io/grpc/internal/InternalSubchannel.java index d221803c93..1ec7f167a8 100644 --- a/core/src/main/java/io/grpc/internal/InternalSubchannel.java +++ b/core/src/main/java/io/grpc/internal/InternalSubchannel.java @@ -118,8 +118,8 @@ final class InternalSubchannel implements WithLogId { new ArrayList(); // Must only be used from channelExecutor - private final InUseStateAggregator2 inUseStateAggregator = - new InUseStateAggregator2() { + private final InUseStateAggregator inUseStateAggregator = + new InUseStateAggregator() { @Override void handleInUse() { callback.onInUse(InternalSubchannel.this); diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl2.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java similarity index 96% rename from core/src/main/java/io/grpc/internal/ManagedChannelImpl2.java rename to core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index 04b7474190..bc75ea1af7 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl2.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -51,9 +51,9 @@ import io.grpc.CompressorRegistry; import io.grpc.ConnectivityStateInfo; import io.grpc.DecompressorRegistry; import io.grpc.EquivalentAddressGroup; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -81,8 +81,8 @@ import javax.annotation.concurrent.ThreadSafe; /** A communication channel for making outgoing RPCs. */ @ThreadSafe -public final class ManagedChannelImpl2 extends ManagedChannel implements WithLogId { - private static final Logger log = Logger.getLogger(ManagedChannelImpl2.class.getName()); +public final class ManagedChannelImpl extends ManagedChannel implements WithLogId { + private static final Logger log = Logger.getLogger(ManagedChannelImpl.class.getName()); // Matching this pattern means the target string is a URI target or at least intended to be one. // A URI target must be an absolute hierarchical URI. @@ -102,7 +102,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog private final String target; private final NameResolver.Factory nameResolverFactory; private final Attributes nameResolverParams; - private final LoadBalancer2.Factory loadBalancerFactory; + private final LoadBalancer.Factory loadBalancerFactory; private final ClientTransportFactory transportFactory; private final Executor executor; private final ObjectPool executorPool; @@ -140,7 +140,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog // null when channel is in idle mode. Must be assigned from channelExecutor. @Nullable - private LoadBalancer2 loadBalancer; + private LoadBalancer loadBalancer; // Must be assigned from channelExecutor. null if channel is in idle mode. @Nullable @@ -155,7 +155,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog private final Set oobChannels = new HashSet(1, .75f); // reprocess() must be run from channelExecutor - private final DelayedClientTransport2 delayedTransport; + private final DelayedClientTransport delayedTransport; // Shutdown states. // @@ -234,8 +234,8 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog // Must be accessed from channelExecutor @VisibleForTesting - final InUseStateAggregator2 inUseStateAggregator = - new InUseStateAggregator2() { + final InUseStateAggregator inUseStateAggregator = + new InUseStateAggregator() { @Override void handleInUse() { exitIdleMode(); @@ -381,9 +381,9 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog } }; - ManagedChannelImpl2(String target, BackoffPolicy.Provider backoffPolicyProvider, + ManagedChannelImpl(String target, BackoffPolicy.Provider backoffPolicyProvider, NameResolver.Factory nameResolverFactory, Attributes nameResolverParams, - LoadBalancer2.Factory loadBalancerFactory, ClientTransportFactory transportFactory, + LoadBalancer.Factory loadBalancerFactory, ClientTransportFactory transportFactory, DecompressorRegistry decompressorRegistry, CompressorRegistry compressorRegistry, ObjectPool timerServicePool, ObjectPool executorPool, ObjectPool oobExecutorPool, @@ -398,7 +398,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog this.executorPool = checkNotNull(executorPool, "executorPool"); this.oobExecutorPool = checkNotNull(oobExecutorPool, "oobExecutorPool"); this.executor = checkNotNull(executorPool.getObject(), "executor"); - this.delayedTransport = new DelayedClientTransport2(this.executor, this.channelExecutor); + this.delayedTransport = new DelayedClientTransport(this.executor, this.channelExecutor); this.delayedTransport.start(delayedTransportListener); this.backoffPolicyProvider = backoffPolicyProvider; this.transportFactory = @@ -473,7 +473,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog * cancelled. */ @Override - public ManagedChannelImpl2 shutdown() { + public ManagedChannelImpl shutdown() { log.log(Level.FINE, "[{0}] shutdown() called", getLogId()); if (!shutdown.compareAndSet(false, true)) { return this; @@ -495,7 +495,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog * return {@code false} immediately after this method returns. */ @Override - public ManagedChannelImpl2 shutdownNow() { + public ManagedChannelImpl shutdownNow() { log.log(Level.FINE, "[{0}] shutdownNow() called", getLogId()); shutdown(); delayedTransport.shutdownNow(SHUTDOWN_NOW_STATUS); @@ -547,7 +547,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog CallOptions callOptions) { Executor executor = callOptions.getExecutor(); if (executor == null) { - executor = ManagedChannelImpl2.this.executor; + executor = ManagedChannelImpl.this.executor; } StatsTraceContext statsTraceCtx = StatsTraceContext.newClientContext( method.getFullMethodName(), statsFactory, stopwatchSupplier); @@ -588,8 +588,8 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog } } - private class LbHelperImpl extends LoadBalancer2.Helper { - LoadBalancer2 lb; + private class LbHelperImpl extends LoadBalancer.Helper { + LoadBalancer lb; final NameResolver nr; LbHelperImpl(NameResolver nr) { @@ -702,7 +702,7 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog @Override public String getAuthority() { - return ManagedChannelImpl2.this.authority(); + return ManagedChannelImpl.this.authority(); } @Override @@ -733,8 +733,8 @@ public final class ManagedChannelImpl2 extends ManagedChannel implements WithLog } private class NameResolverListenerImpl implements NameResolver.Listener { - final LoadBalancer2 balancer; - final LoadBalancer2.Helper helper; + final LoadBalancer balancer; + final LoadBalancer.Helper helper; NameResolverListenerImpl(LbHelperImpl helperImpl) { this.balancer = helperImpl.lb; diff --git a/core/src/main/java/io/grpc/internal/OobChannel.java b/core/src/main/java/io/grpc/internal/OobChannel.java index 0dfdfedbef..996f0e9f81 100644 --- a/core/src/main/java/io/grpc/internal/OobChannel.java +++ b/core/src/main/java/io/grpc/internal/OobChannel.java @@ -41,9 +41,9 @@ import io.grpc.CallOptions; import io.grpc.ClientCall; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -58,7 +58,7 @@ import java.util.logging.Logger; import javax.annotation.concurrent.ThreadSafe; /** - * A ManagedChannel backed by a single {@link InternalSubchannel} and used for {@link LoadBalancer2} + * A ManagedChannel backed by a single {@link InternalSubchannel} and used for {@link LoadBalancer} * to its own RPC needs. */ @ThreadSafe @@ -71,7 +71,7 @@ final class OobChannel extends ManagedChannel implements WithLogId { private final LogId logId = LogId.allocate(getClass().getName()); private final StatsContextFactory statsFactory; private final String authority; - private final DelayedClientTransport2 delayedTransport; + private final DelayedClientTransport delayedTransport; private final ObjectPool executorPool; private final Executor executor; private final ScheduledExecutorService deadlineCancellationExecutor; @@ -100,7 +100,7 @@ final class OobChannel extends ManagedChannel implements WithLogId { this.deadlineCancellationExecutor = checkNotNull( deadlineCancellationExecutor, "deadlineCancellationExecutor"); this.stopwatchSupplier = checkNotNull(stopwatchSupplier, "stopwatchSupplier"); - this.delayedTransport = new DelayedClientTransport2(executor, channelExecutor); + this.delayedTransport = new DelayedClientTransport(executor, channelExecutor); this.delayedTransport.start(new ManagedClientTransport.Listener() { @Override public void transportShutdown(Status s) { diff --git a/core/src/main/java/io/grpc/internal/SubchannelImpl.java b/core/src/main/java/io/grpc/internal/SubchannelImpl.java index c35218701f..1a966ae471 100644 --- a/core/src/main/java/io/grpc/internal/SubchannelImpl.java +++ b/core/src/main/java/io/grpc/internal/SubchannelImpl.java @@ -31,14 +31,14 @@ package io.grpc.internal; -import io.grpc.LoadBalancer2; +import io.grpc.LoadBalancer; import javax.annotation.Nullable; /** * The base interface of the Subchannels returned by {@link - * io.grpc.LoadBalancer2.Helper#createSubchannel}. + * io.grpc.LoadBalancer.Helper#createSubchannel}. */ -abstract class SubchannelImpl extends LoadBalancer2.Subchannel { +abstract class SubchannelImpl extends LoadBalancer.Subchannel { /** * Same as {@link InternalSubchannel#obtainActiveTransport}. */ diff --git a/core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory2.java b/core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory.java similarity index 88% rename from core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory2.java rename to core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory.java index 072a5318bc..20b36bb421 100644 --- a/core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory2.java +++ b/core/src/main/java/io/grpc/util/RoundRobinLoadBalancerFactory.java @@ -41,10 +41,10 @@ import io.grpc.Attributes; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; import io.grpc.ExperimentalApi; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.Subchannel; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.Subchannel; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.Metadata; import io.grpc.NameResolver; import io.grpc.ResolvedServerInfo; @@ -64,35 +64,30 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; /** - * A {@link LoadBalancer2} that provides round-robin load balancing mechanism over the + * A {@link LoadBalancer} that provides round-robin load balancing mechanism over the * addresses from the {@link NameResolver}. The sub-lists received from the name resolver * are considered to be an {@link EquivalentAddressGroup} and each of these sub-lists is * what is then balanced across. - * - *

TECHNICAL PREVIEW: The name of this class is temporary. It will be renamed to - * {@code RoundRobinLoadBalancerFactory} 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 class RoundRobinLoadBalancerFactory2 extends LoadBalancer2.Factory { - private static final RoundRobinLoadBalancerFactory2 INSTANCE = - new RoundRobinLoadBalancerFactory2(); +public class RoundRobinLoadBalancerFactory extends LoadBalancer.Factory { + private static final RoundRobinLoadBalancerFactory INSTANCE = + new RoundRobinLoadBalancerFactory(); - private RoundRobinLoadBalancerFactory2() { + private RoundRobinLoadBalancerFactory() { } - public static RoundRobinLoadBalancerFactory2 getInstance() { + public static RoundRobinLoadBalancerFactory getInstance() { return INSTANCE; } @Override - public LoadBalancer2 newLoadBalancer(LoadBalancer2.Helper helper) { + public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper) { return new RoundRobinLoadBalancer(helper); } @VisibleForTesting - static class RoundRobinLoadBalancer extends LoadBalancer2 { + static class RoundRobinLoadBalancer extends LoadBalancer { private final Helper helper; private final Map subchannels = new HashMap(); @@ -101,13 +96,13 @@ public class RoundRobinLoadBalancerFactory2 extends LoadBalancer2.Factory { static final Attributes.Key> STATE_INFO = Attributes.Key.of("state-info"); - public RoundRobinLoadBalancer(Helper helper) { - this.helper = helper; + RoundRobinLoadBalancer(Helper helper) { + this.helper = checkNotNull(helper, "helper"); } @Override - public void handleResolvedAddresses(List servers, - Attributes attributes) { + public void handleResolvedAddresses( + List servers, Attributes attributes) { Set currentAddrs = subchannels.keySet(); Set latestAddrs = resolvedServerInfoGroupToEquivalentAddressGroup(servers); @@ -237,7 +232,7 @@ public class RoundRobinLoadBalancerFactory2 extends LoadBalancer2.Factory { } @VisibleForTesting - static class Picker extends SubchannelPicker { + static final class Picker extends SubchannelPicker { @Nullable private final Status status; private final List list; diff --git a/core/src/test/java/io/grpc/PickFirstLoadBalancer2Test.java b/core/src/test/java/io/grpc/PickFirstLoadBalancerTest.java similarity index 96% rename from core/src/test/java/io/grpc/PickFirstLoadBalancer2Test.java rename to core/src/test/java/io/grpc/PickFirstLoadBalancerTest.java index 541f6da456..d8d1505a29 100644 --- a/core/src/test/java/io/grpc/PickFirstLoadBalancer2Test.java +++ b/core/src/test/java/io/grpc/PickFirstLoadBalancerTest.java @@ -44,11 +44,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import com.google.common.collect.Lists; -import io.grpc.LoadBalancer2.Helper; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.Subchannel; -import io.grpc.PickFirstBalancerFactory2.PickFirstBalancer; -import io.grpc.PickFirstBalancerFactory2.Picker; +import io.grpc.LoadBalancer.Helper; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.Subchannel; +import io.grpc.PickFirstBalancerFactory.PickFirstBalancer; +import io.grpc.PickFirstBalancerFactory.Picker; import java.net.SocketAddress; import java.util.List; import org.junit.Before; @@ -62,9 +62,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -/** Unit test for {@link PickFirstBalancerFactory2}. */ +/** Unit test for {@link PickFirstBalancerFactory}. */ @RunWith(JUnit4.class) -public class PickFirstLoadBalancer2Test { +public class PickFirstLoadBalancerTest { private PickFirstBalancer loadBalancer; private List servers = Lists.newArrayList(); private List socketAddresses = Lists.newArrayList(); @@ -96,7 +96,7 @@ public class PickFirstLoadBalancer2Test { when(mockHelper.createSubchannel(any(EquivalentAddressGroup.class), any(Attributes.class))) .thenReturn(mockSubchannel); - loadBalancer = (PickFirstBalancer) PickFirstBalancerFactory2.getInstance().newLoadBalancer( + loadBalancer = (PickFirstBalancer) PickFirstBalancerFactory.getInstance().newLoadBalancer( mockHelper); } diff --git a/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java b/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java index c825a5f05f..3413e77815 100644 --- a/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java +++ b/core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java @@ -78,11 +78,11 @@ public class AbstractManagedChannelImplBuilderTest { builder.getIdleTimeoutMillis()); builder.idleTimeout(Long.MAX_VALUE, TimeUnit.DAYS); - assertEquals(ManagedChannelImpl2.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis()); + assertEquals(ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis()); builder.idleTimeout(AbstractManagedChannelImplBuilder.IDLE_MODE_MAX_TIMEOUT_DAYS, TimeUnit.DAYS); - assertEquals(ManagedChannelImpl2.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis()); + assertEquals(ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE, builder.getIdleTimeoutMillis()); try { builder.idleTimeout(0, TimeUnit.SECONDS); diff --git a/core/src/test/java/io/grpc/internal/DelayedClientTransport2Test.java b/core/src/test/java/io/grpc/internal/DelayedClientTransportTest.java similarity index 99% rename from core/src/test/java/io/grpc/internal/DelayedClientTransport2Test.java rename to core/src/test/java/io/grpc/internal/DelayedClientTransportTest.java index a2c503d674..39f7aee463 100644 --- a/core/src/test/java/io/grpc/internal/DelayedClientTransport2Test.java +++ b/core/src/test/java/io/grpc/internal/DelayedClientTransportTest.java @@ -51,8 +51,8 @@ import static org.mockito.Mockito.when; import io.grpc.Attributes; import io.grpc.CallOptions; import io.grpc.IntegerMarshaller; -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.MethodDescriptor.MethodType; @@ -76,10 +76,10 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** - * Unit tests for {@link DelayedClientTransport2}. + * Unit tests for {@link DelayedClientTransport}. */ @RunWith(JUnit4.class) -public class DelayedClientTransport2Test { +public class DelayedClientTransportTest { @Mock private ManagedClientTransport.Listener transportListener; @Mock private SubchannelPicker mockPicker; @Mock private SubchannelImpl mockSubchannel; @@ -117,7 +117,7 @@ public class DelayedClientTransport2Test { private final FakeClock fakeExecutor = new FakeClock(); - private final DelayedClientTransport2 delayedTransport = new DelayedClientTransport2( + private final DelayedClientTransport delayedTransport = new DelayedClientTransport( fakeExecutor.getScheduledExecutorService(), new ChannelExecutor()); @Before public void setUp() { diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplGetNameResolverTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplGetNameResolverTest.java index 3e57b626ac..cd6d59901d 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImplGetNameResolverTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplGetNameResolverTest.java @@ -43,7 +43,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** Unit tests for {@link ManagedChannelImpl2#getNameResolver}. */ +/** Unit tests for {@link ManagedChannelImpl#getNameResolver}. */ @RunWith(JUnit4.class) public class ManagedChannelImplGetNameResolverTest { private static final Attributes NAME_RESOLVER_PARAMS = @@ -121,7 +121,7 @@ public class ManagedChannelImplGetNameResolverTest { } }; try { - ManagedChannelImpl2.getNameResolver( + ManagedChannelImpl.getNameResolver( "foo.googleapis.com:8080", nameResolverFactory, NAME_RESOLVER_PARAMS); fail("Should fail"); } catch (IllegalArgumentException e) { @@ -131,7 +131,7 @@ public class ManagedChannelImplGetNameResolverTest { private void testValidTarget(String target, String expectedUriString, URI expectedUri) { Factory nameResolverFactory = new FakeNameResolverFactory(expectedUri.getScheme()); - FakeNameResolver nameResolver = (FakeNameResolver) ManagedChannelImpl2.getNameResolver( + FakeNameResolver nameResolver = (FakeNameResolver) ManagedChannelImpl.getNameResolver( target, nameResolverFactory, NAME_RESOLVER_PARAMS); assertNotNull(nameResolver); assertEquals(expectedUri, nameResolver.uri); @@ -142,7 +142,7 @@ public class ManagedChannelImplGetNameResolverTest { Factory nameResolverFactory = new FakeNameResolverFactory("dns"); try { - FakeNameResolver nameResolver = (FakeNameResolver) ManagedChannelImpl2.getNameResolver( + FakeNameResolver nameResolver = (FakeNameResolver) ManagedChannelImpl.getNameResolver( target, nameResolverFactory, NAME_RESOLVER_PARAMS); fail("Should have failed, but got resolver with " + nameResolver.uri); } catch (IllegalArgumentException e) { diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImpl2IdlenessTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplIdlenessTest.java similarity index 96% rename from core/src/test/java/io/grpc/internal/ManagedChannelImpl2IdlenessTest.java rename to core/src/test/java/io/grpc/internal/ManagedChannelImplIdlenessTest.java index f3b64bb548..d205038075 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImpl2IdlenessTest.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplIdlenessTest.java @@ -52,11 +52,11 @@ import io.grpc.CompressorRegistry; import io.grpc.DecompressorRegistry; import io.grpc.EquivalentAddressGroup; import io.grpc.IntegerMarshaller; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.Helper; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.Subchannel; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.Helper; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.Subchannel; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -90,14 +90,14 @@ import org.mockito.MockitoAnnotations; * Unit tests for {@link ManagedChannelImpl}'s idle mode. */ @RunWith(JUnit4.class) -public class ManagedChannelImpl2IdlenessTest { +public class ManagedChannelImplIdlenessTest { private final FakeClock timer = new FakeClock(); private final FakeClock executor = new FakeClock(); private final FakeClock oobExecutor = new FakeClock(); private static final String AUTHORITY = "fakeauthority"; private static final String USER_AGENT = "fakeagent"; private static final long IDLE_TIMEOUT_SECONDS = 30; - private ManagedChannelImpl2 channel; + private ManagedChannelImpl channel; private final MethodDescriptor method = MethodDescriptor.newBuilder() @@ -115,8 +115,8 @@ public class ManagedChannelImpl2IdlenessTest { @Mock private ObjectPool executorPool; @Mock private ObjectPool oobExecutorPool; @Mock private ClientTransportFactory mockTransportFactory; - @Mock private LoadBalancer2 mockLoadBalancer; - @Mock private LoadBalancer2.Factory mockLoadBalancerFactory; + @Mock private LoadBalancer mockLoadBalancer; + @Mock private LoadBalancer.Factory mockLoadBalancerFactory; @Mock private NameResolver mockNameResolver; @Mock private NameResolver.Factory mockNameResolverFactory; @Mock private ClientCall.Listener mockCallListener; @@ -136,7 +136,7 @@ public class ManagedChannelImpl2IdlenessTest { .newNameResolver(any(URI.class), any(Attributes.class))) .thenReturn(mockNameResolver); - channel = new ManagedChannelImpl2("fake://target", new FakeBackoffPolicyProvider(), + channel = new ManagedChannelImpl("fake://target", new FakeBackoffPolicyProvider(), mockNameResolverFactory, Attributes.EMPTY, mockLoadBalancerFactory, mockTransportFactory, DecompressorRegistry.getDefaultInstance(), CompressorRegistry.getDefaultInstance(), timerServicePool, executorPool, oobExecutorPool, diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImpl2Test.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java similarity index 97% rename from core/src/test/java/io/grpc/internal/ManagedChannelImpl2Test.java rename to core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java index af2586a08f..8bca0a48c5 100644 --- a/core/src/test/java/io/grpc/internal/ManagedChannelImpl2Test.java +++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java @@ -71,11 +71,11 @@ import io.grpc.Context; import io.grpc.DecompressorRegistry; import io.grpc.EquivalentAddressGroup; import io.grpc.IntegerMarshaller; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.Helper; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.Subchannel; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.Helper; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.Subchannel; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -116,9 +116,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -/** Unit tests for {@link ManagedChannelImpl2}. */ +/** Unit tests for {@link ManagedChannelImpl}. */ @RunWith(JUnit4.class) -public class ManagedChannelImpl2Test { +public class ManagedChannelImplTest { private static final List NO_INTERCEPTOR = Collections.emptyList(); private static final Attributes NAME_RESOLVER_PARAMS = @@ -147,16 +147,16 @@ public class ManagedChannelImpl2Test { @Rule public final ExpectedException thrown = ExpectedException.none(); - private ManagedChannelImpl2 channel; + private ManagedChannelImpl channel; private Helper helper; @Captor private ArgumentCaptor statusCaptor; @Captor private ArgumentCaptor statsTraceCtxCaptor; @Mock - private LoadBalancer2.Factory mockLoadBalancerFactory; + private LoadBalancer.Factory mockLoadBalancerFactory; @Mock - private LoadBalancer2 mockLoadBalancer; + private LoadBalancer mockLoadBalancer; @Captor private ArgumentCaptor stateInfoCaptor; @Mock @@ -188,11 +188,11 @@ public class ManagedChannelImpl2Test { private void createChannel( NameResolver.Factory nameResolverFactory, List interceptors) { - channel = new ManagedChannelImpl2(target, new FakeBackoffPolicyProvider(), + channel = new ManagedChannelImpl(target, new FakeBackoffPolicyProvider(), nameResolverFactory, NAME_RESOLVER_PARAMS, mockLoadBalancerFactory, mockTransportFactory, DecompressorRegistry.getDefaultInstance(), CompressorRegistry.getDefaultInstance(), timerServicePool, executorPool, oobExecutorPool, - timer.getStopwatchSupplier(), ManagedChannelImpl2.IDLE_TIMEOUT_MILLIS_DISABLE, userAgent, + timer.getStopwatchSupplier(), ManagedChannelImpl.IDLE_TIMEOUT_MILLIS_DISABLE, userAgent, interceptors, statsCtxFactory); // Force-exit the initial idle-mode channel.exitIdleMode(); @@ -365,7 +365,7 @@ public class ManagedChannelImpl2Test { assertTrue(nameResolverFactory.resolvers.get(0).shutdown); // call should have been aborted by delayed transport executor.runDueTasks(); - verify(mockCallListener).onClose(same(ManagedChannelImpl2.SHUTDOWN_NOW_STATUS), + verify(mockCallListener).onClose(same(ManagedChannelImpl.SHUTDOWN_NOW_STATUS), any(Metadata.class)); } else { // LoadBalancer and NameResolver are still running. @@ -389,7 +389,7 @@ public class ManagedChannelImpl2Test { if (shutdownNow) { // Channel shutdownNow() all subchannels after shutting down LoadBalancer - verify(mockTransport).shutdownNow(ManagedChannelImpl2.SHUTDOWN_NOW_STATUS); + verify(mockTransport).shutdownNow(ManagedChannelImpl.SHUTDOWN_NOW_STATUS); } else { verify(mockTransport, never()).shutdownNow(any(Status.class)); } @@ -755,7 +755,7 @@ public class ManagedChannelImpl2Test { // shutdown() has a delay sub1.shutdown(); - timer.forwardTime(ManagedChannelImpl2.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS - 1, TimeUnit.SECONDS); + timer.forwardTime(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS - 1, TimeUnit.SECONDS); sub1.shutdown(); verify(transportInfo1.transport, never()).shutdown(); timer.forwardTime(1, TimeUnit.SECONDS); @@ -991,12 +991,12 @@ public class ManagedChannelImpl2Test { @Test public void uriPattern() { - assertTrue(ManagedChannelImpl2.URI_PATTERN.matcher("a:/").matches()); - assertTrue(ManagedChannelImpl2.URI_PATTERN.matcher("Z019+-.:/!@ #~ ").matches()); - assertFalse(ManagedChannelImpl2.URI_PATTERN.matcher("a/:").matches()); // "/:" not matched - assertFalse(ManagedChannelImpl2.URI_PATTERN.matcher("0a:/").matches()); // '0' not matched - assertFalse(ManagedChannelImpl2.URI_PATTERN.matcher("a,:/").matches()); // ',' not matched - assertFalse(ManagedChannelImpl2.URI_PATTERN.matcher(" a:/").matches()); // space not matched + assertTrue(ManagedChannelImpl.URI_PATTERN.matcher("a:/").matches()); + assertTrue(ManagedChannelImpl.URI_PATTERN.matcher("Z019+-.:/!@ #~ ").matches()); + assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("a/:").matches()); // "/:" not matched + assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("0a:/").matches()); // '0' not matched + assertFalse(ManagedChannelImpl.URI_PATTERN.matcher("a,:/").matches()); // ',' not matched + assertFalse(ManagedChannelImpl.URI_PATTERN.matcher(" a:/").matches()); // space not matched } /** diff --git a/core/src/test/java/io/grpc/util/RoundRobinLoadBalancer2Test.java b/core/src/test/java/io/grpc/util/RoundRobinLoadBalancerTest.java similarity index 95% rename from core/src/test/java/io/grpc/util/RoundRobinLoadBalancer2Test.java rename to core/src/test/java/io/grpc/util/RoundRobinLoadBalancerTest.java index fb28afa496..d260919bbc 100644 --- a/core/src/test/java/io/grpc/util/RoundRobinLoadBalancer2Test.java +++ b/core/src/test/java/io/grpc/util/RoundRobinLoadBalancerTest.java @@ -34,7 +34,7 @@ package io.grpc.util; import static com.google.common.truth.Truth.assertThat; import static io.grpc.ConnectivityState.IDLE; import static io.grpc.ConnectivityState.READY; -import static io.grpc.util.RoundRobinLoadBalancerFactory2.RoundRobinLoadBalancer.STATE_INFO; +import static io.grpc.util.RoundRobinLoadBalancerFactory.RoundRobinLoadBalancer.STATE_INFO; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Matchers.any; @@ -53,15 +53,15 @@ import io.grpc.Attributes; import io.grpc.ConnectivityState; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.Helper; -import io.grpc.LoadBalancer2.Subchannel; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.Helper; +import io.grpc.LoadBalancer.Subchannel; import io.grpc.Metadata; import io.grpc.ResolvedServerInfo; import io.grpc.ResolvedServerInfoGroup; import io.grpc.Status; -import io.grpc.util.RoundRobinLoadBalancerFactory2.Picker; -import io.grpc.util.RoundRobinLoadBalancerFactory2.RoundRobinLoadBalancer; +import io.grpc.util.RoundRobinLoadBalancerFactory.Picker; +import io.grpc.util.RoundRobinLoadBalancerFactory.RoundRobinLoadBalancer; import java.net.SocketAddress; import java.util.Collections; import java.util.List; @@ -79,9 +79,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -/** Unit test for {@link RoundRobinLoadBalancerFactory2}. */ +/** Unit test for {@link RoundRobinLoadBalancerFactory}. */ @RunWith(JUnit4.class) -public class RoundRobinLoadBalancer2Test { +public class RoundRobinLoadBalancerTest { private RoundRobinLoadBalancer loadBalancer; private Map servers = Maps.newHashMap(); private Map subchannels = Maps.newLinkedHashMap(); @@ -117,7 +117,7 @@ public class RoundRobinLoadBalancer2Test { } }); - loadBalancer = (RoundRobinLoadBalancer) RoundRobinLoadBalancerFactory2.getInstance() + loadBalancer = (RoundRobinLoadBalancer) RoundRobinLoadBalancerFactory.getInstance() .newLoadBalancer(mockHelper); } @@ -323,7 +323,7 @@ public class RoundRobinLoadBalancer2Test { Status error = Status.NOT_FOUND.withDescription("nameResolutionError"); loadBalancer.handleNameResolutionError(error); verify(mockHelper).updatePicker(pickerCaptor.capture()); - LoadBalancer2.PickResult pickResult = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, + LoadBalancer.PickResult pickResult = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, new Metadata()); assertNull(pickResult.getSubchannel()); assertEquals(error, pickResult.getStatus()); @@ -341,12 +341,12 @@ public class RoundRobinLoadBalancer2Test { any(Attributes.class)); verify(mockHelper, times(2)).updatePicker(pickerCaptor.capture()); - LoadBalancer2.PickResult pickResult = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, + LoadBalancer.PickResult pickResult = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, new Metadata()); assertEquals(readySubchannel, pickResult.getSubchannel()); assertEquals(Status.OK.getCode(), pickResult.getStatus().getCode()); - LoadBalancer2.PickResult pickResult2 = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, + LoadBalancer.PickResult pickResult2 = pickerCaptor.getValue().pickSubchannel(Attributes.EMPTY, new Metadata()); assertEquals(readySubchannel, pickResult2.getSubchannel()); verifyNoMoreInteractions(mockHelper); diff --git a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer2.java b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java similarity index 98% rename from grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer2.java rename to grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java index d3b95071fb..63fa54baae 100644 --- a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer2.java +++ b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancer.java @@ -43,7 +43,7 @@ import com.google.common.annotations.VisibleForTesting; import io.grpc.Attributes; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; -import io.grpc.LoadBalancer2; +import io.grpc.LoadBalancer; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.ResolvedServerInfoGroup; @@ -67,13 +67,13 @@ import java.util.logging.Logger; import javax.annotation.Nullable; /** - * A {@link LoadBalancer2} that uses the GRPCLB protocol. + * A {@link LoadBalancer} that uses the GRPCLB protocol. * *

Optionally, when requested by the naming system, will delegate the work to a local pick-first * or round-robin balancer. */ -class GrpclbLoadBalancer2 extends LoadBalancer2 implements WithLogId { - private static final Logger logger = Logger.getLogger(GrpclbLoadBalancer2.class.getName()); +class GrpclbLoadBalancer extends LoadBalancer implements WithLogId { + private static final Logger logger = Logger.getLogger(GrpclbLoadBalancer.class.getName()); @VisibleForTesting static final SubchannelPicker BUFFER_PICKER = new SubchannelPicker() { @@ -104,7 +104,7 @@ class GrpclbLoadBalancer2 extends LoadBalancer2 implements WithLogId { // If not null, all work is delegated to it. @Nullable - private LoadBalancer2 delegate; + private LoadBalancer delegate; private LbPolicy lbPolicy; /////////////////////////////////////////////////////////////////////////////// @@ -128,7 +128,7 @@ class GrpclbLoadBalancer2 extends LoadBalancer2 implements WithLogId { // A null element indicate a simulated error for throttling purpose private List roundRobinList = Collections.emptyList(); - GrpclbLoadBalancer2(Helper helper, Factory pickFirstBalancerFactory, + GrpclbLoadBalancer(Helper helper, Factory pickFirstBalancerFactory, Factory roundRobinBalancerFactory) { this.helper = checkNotNull(helper, "helper"); this.serviceName = checkNotNull(helper.getAuthority(), "helper returns null authority"); @@ -450,7 +450,7 @@ class GrpclbLoadBalancer2 extends LoadBalancer2 implements WithLogId { } @VisibleForTesting - LoadBalancer2 getDelegate() { + LoadBalancer getDelegate() { return delegate; } diff --git a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory2.java b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory.java similarity index 66% rename from grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory2.java rename to grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory.java index 3471265740..8ac2ffe68c 100644 --- a/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory2.java +++ b/grpclb/src/main/java/io/grpc/grpclb/GrpclbLoadBalancerFactory.java @@ -32,36 +32,32 @@ package io.grpc.grpclb; import io.grpc.ExperimentalApi; -import io.grpc.LoadBalancer2; -import io.grpc.PickFirstBalancerFactory2; -import io.grpc.util.RoundRobinLoadBalancerFactory2; +import io.grpc.LoadBalancer; +import io.grpc.PickFirstBalancerFactory; +import io.grpc.util.RoundRobinLoadBalancerFactory; /** - * A factory for {@link LoadBalancer2}s that uses the GRPCLB protocol. - * - *

TECHNICAL PREVIEW: The name of this class is temporary. It will be renamed to - * {@code GrpclbLoadBalancerFactory} during - * transition to LBv2. You should use it only if you want to experiment the LBv2 code path. + * A factory for {@link LoadBalancer}s that uses the GRPCLB protocol. * *

Experimental:This only works with the GRPCLB load-balancer service, which is not * available yet. Right now it's only good for internal testing. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1782") -public class GrpclbLoadBalancerFactory2 extends LoadBalancer2.Factory { +public class GrpclbLoadBalancerFactory extends LoadBalancer.Factory { - private static final GrpclbLoadBalancerFactory2 instance = new GrpclbLoadBalancerFactory2(); + private static final GrpclbLoadBalancerFactory instance = new GrpclbLoadBalancerFactory(); - private GrpclbLoadBalancerFactory2() { + private GrpclbLoadBalancerFactory() { } - public static GrpclbLoadBalancerFactory2 getInstance() { + public static GrpclbLoadBalancerFactory getInstance() { return instance; } @Override - public LoadBalancer2 newLoadBalancer(LoadBalancer2.Helper helper) { - return new GrpclbLoadBalancer2( - helper, PickFirstBalancerFactory2.getInstance(), - RoundRobinLoadBalancerFactory2.getInstance()); + public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper) { + return new GrpclbLoadBalancer( + helper, PickFirstBalancerFactory.getInstance(), + RoundRobinLoadBalancerFactory.getInstance()); } } diff --git a/grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancer2Test.java b/grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancerTest.java similarity index 97% rename from grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancer2Test.java rename to grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancerTest.java index 28d25fd749..a99e0db26d 100644 --- a/grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancer2Test.java +++ b/grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancerTest.java @@ -62,11 +62,11 @@ import io.grpc.Attributes; import io.grpc.CallOptions; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; -import io.grpc.LoadBalancer2; -import io.grpc.LoadBalancer2.Helper; -import io.grpc.LoadBalancer2.PickResult; -import io.grpc.LoadBalancer2.Subchannel; -import io.grpc.LoadBalancer2.SubchannelPicker; +import io.grpc.LoadBalancer; +import io.grpc.LoadBalancer.Helper; +import io.grpc.LoadBalancer.PickResult; +import io.grpc.LoadBalancer.Subchannel; +import io.grpc.LoadBalancer.SubchannelPicker; import io.grpc.ManagedChannel; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -76,8 +76,8 @@ import io.grpc.ResolvedServerInfoGroup; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.grpclb.GrpclbConstants.LbPolicy; -import io.grpc.grpclb.GrpclbLoadBalancer2.ErrorPicker; -import io.grpc.grpclb.GrpclbLoadBalancer2.RoundRobinPicker; +import io.grpc.grpclb.GrpclbLoadBalancer.ErrorPicker; +import io.grpc.grpclb.GrpclbLoadBalancer.RoundRobinPicker; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.inprocess.InProcessServerBuilder; import io.grpc.internal.SerializingExecutor; @@ -105,9 +105,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -/** Unit tests for {@link GrpclbLoadBalancer2}. */ +/** Unit tests for {@link GrpclbLoadBalancer}. */ @RunWith(JUnit4.class) -public class GrpclbLoadBalancer2Test { +public class GrpclbLoadBalancerTest { private static final Attributes.Key RESOLUTION_ATTR = Attributes.Key.of("resolution-attr"); private static final String SERVICE_AUTHORITY = "api.google.com"; @@ -159,14 +159,14 @@ public class GrpclbLoadBalancer2Test { new SerializingExecutor(MoreExecutors.directExecutor()); private final Metadata headers = new Metadata(); @Mock - private LoadBalancer2.Factory pickFirstBalancerFactory; + private LoadBalancer.Factory pickFirstBalancerFactory; @Mock - private LoadBalancer2 pickFirstBalancer; + private LoadBalancer pickFirstBalancer; @Mock - private LoadBalancer2.Factory roundRobinBalancerFactory; + private LoadBalancer.Factory roundRobinBalancerFactory; @Mock - private LoadBalancer2 roundRobinBalancer; - private GrpclbLoadBalancer2 balancer; + private LoadBalancer roundRobinBalancer; + private GrpclbLoadBalancer balancer; @SuppressWarnings("unchecked") @Before @@ -240,7 +240,7 @@ public class GrpclbLoadBalancer2Test { } }).when(helper).runSerialized(any(Runnable.class)); when(helper.getAuthority()).thenReturn(SERVICE_AUTHORITY); - balancer = new GrpclbLoadBalancer2(helper, pickFirstBalancerFactory, roundRobinBalancerFactory); + balancer = new GrpclbLoadBalancer(helper, pickFirstBalancerFactory, roundRobinBalancerFactory); } @After @@ -290,7 +290,7 @@ public class GrpclbLoadBalancer2Test { @Test public void bufferPicker() { assertEquals(PickResult.withNoResult(), - GrpclbLoadBalancer2.BUFFER_PICKER.pickSubchannel(Attributes.EMPTY, headers)); + GrpclbLoadBalancer.BUFFER_PICKER.pickSubchannel(Attributes.EMPTY, headers)); } @Test @@ -553,11 +553,11 @@ public class GrpclbLoadBalancer2Test { assertEquals(new EquivalentAddressGroup(backends1.get(1)), subchannel2.getAddresses()); // Before any subchannel is READY, a buffer picker will be provided - inOrder.verify(helper).updatePicker(same(GrpclbLoadBalancer2.BUFFER_PICKER)); + inOrder.verify(helper).updatePicker(same(GrpclbLoadBalancer.BUFFER_PICKER)); deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(CONNECTING)); deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(CONNECTING)); - inOrder.verify(helper, times(2)).updatePicker(same(GrpclbLoadBalancer2.BUFFER_PICKER)); + inOrder.verify(helper, times(2)).updatePicker(same(GrpclbLoadBalancer.BUFFER_PICKER)); // Let subchannels be connected deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(READY)); @@ -724,7 +724,7 @@ public class GrpclbLoadBalancer2Test { eq(new EquivalentAddressGroup(backends.get(0))), any(Attributes.class)); inOrder.verify(helper).createSubchannel( eq(new EquivalentAddressGroup(backends.get(1))), any(Attributes.class)); - inOrder.verify(helper).updatePicker(same(GrpclbLoadBalancer2.BUFFER_PICKER)); + inOrder.verify(helper).updatePicker(same(GrpclbLoadBalancer.BUFFER_PICKER)); inOrder.verifyNoMoreInteractions(); } @@ -806,7 +806,7 @@ public class GrpclbLoadBalancer2Test { Subchannel subchannel = subchannels[i]; if (subchannel == null) { assertSame("list[" + i + "] should be drop", - GrpclbLoadBalancer2.THROTTLED_RESULT, picker.list.get(i)); + GrpclbLoadBalancer.THROTTLED_RESULT, picker.list.get(i)); } else { assertEquals("list[" + i + "] should be Subchannel", subchannel, picker.list.get(i).getSubchannel());