• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 
22 import com.google.common.base.MoreObjects;
23 import com.google.common.base.Objects;
24 import com.google.common.base.Preconditions;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.concurrent.ScheduledExecutorService;
31 import javax.annotation.Nonnull;
32 import javax.annotation.Nullable;
33 import javax.annotation.concurrent.Immutable;
34 import javax.annotation.concurrent.NotThreadSafe;
35 import javax.annotation.concurrent.ThreadSafe;
36 
37 /**
38  * A pluggable component that receives resolved addresses from {@link NameResolver} and provides the
39  * channel a usable subchannel when asked.
40  *
41  * <h3>Overview</h3>
42  *
43  * <p>A LoadBalancer typically implements three interfaces:
44  * <ol>
45  *   <li>{@link LoadBalancer} is the main interface.  All methods on it are invoked sequentially
46  *       in the same <strong>synchronization context</strong> (see next section) as returned by
47  *       {@link io.grpc.LoadBalancer.Helper#getSynchronizationContext}.  It receives the results
48  *       from the {@link NameResolver}, updates of subchannels' connectivity states, and the
49  *       channel's request for the LoadBalancer to shutdown.</li>
50  *   <li>{@link SubchannelPicker SubchannelPicker} does the actual load-balancing work.  It selects
51  *       a {@link Subchannel Subchannel} for each new RPC.</li>
52  *   <li>{@link Factory Factory} creates a new {@link LoadBalancer} instance.
53  * </ol>
54  *
55  * <p>{@link Helper Helper} is implemented by gRPC library and provided to {@link Factory
56  * Factory}. It provides functionalities that a {@code LoadBalancer} implementation would typically
57  * need.
58  *
59  * <h3>The Synchronization Context</h3>
60  *
61  * <p>All methods on the {@link LoadBalancer} interface are called from a Synchronization Context,
62  * meaning they are serialized, thus the balancer implementation doesn't need to worry about
63  * synchronization among them.  {@link io.grpc.LoadBalancer.Helper#getSynchronizationContext}
64  * allows implementations to schedule tasks to be run in the same Synchronization Context, with or
65  * without a delay, thus those tasks don't need to worry about synchronizing with the balancer
66  * methods.
67  *
68  * <p>However, the actual running thread may be the network thread, thus the following rules must be
69  * followed to prevent blocking or even dead-locking in a network:
70  *
71  * <ol>
72  *
73  *   <li><strong>Never block in the Synchronization Context</strong>.  The callback methods must
74  *   return quickly.  Examples or work that must be avoided: CPU-intensive calculation, waiting on
75  *   synchronization primitives, blocking I/O, blocking RPCs, etc.</li>
76  *
77  *   <li><strong>Avoid calling into other components with lock held</strong>.  The Synchronization
78  *   Context may be under a lock, e.g., the transport lock of OkHttp.  If your LoadBalancer holds a
79  *   lock in a callback method (e.g., {@link #handleResolvedAddresses handleResolvedAddresses()})
80  *   while calling into another method that also involves locks, be cautious of deadlock.  Generally
81  *   you wouldn't need any locking in the LoadBalancer if you follow the canonical implementation
82  *   pattern below.</li>
83  *
84  * </ol>
85  *
86  * <h3>The canonical implementation pattern</h3>
87  *
88  * <p>A {@link LoadBalancer} keeps states like the latest addresses from NameResolver, the
89  * Subchannel(s) and their latest connectivity states.  These states are mutated within the
90  * Synchronization Context,
91  *
92  * <p>A typical {@link SubchannelPicker SubchannelPicker} holds a snapshot of these states.  It may
93  * have its own states, e.g., a picker from a round-robin load-balancer may keep a pointer to the
94  * next Subchannel, which are typically mutated by multiple threads.  The picker should only mutate
95  * its own state, and should not mutate or re-acquire the states of the LoadBalancer.  This way the
96  * picker only needs to synchronize its own states, which is typically trivial to implement.
97  *
98  * <p>When the LoadBalancer states changes, e.g., Subchannels has become or stopped being READY, and
99  * we want subsequent RPCs to use the latest list of READY Subchannels, LoadBalancer would create a
100  * new picker, which holds a snapshot of the latest Subchannel list.  Refer to the javadoc of {@link
101  * io.grpc.LoadBalancer.SubchannelStateListener#onSubchannelState onSubchannelState()} how to do
102  * this properly.
103  *
104  * <p>No synchronization should be necessary between LoadBalancer and its pickers if you follow
105  * the pattern above.  It may be possible to implement in a different way, but that would usually
106  * result in more complicated threading.
107  *
108  * @since 1.2.0
109  */
110 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
111 @NotThreadSafe
112 public abstract class LoadBalancer {
113 
114   @Internal
115   @NameResolver.ResolutionResultAttr
116   public static final Attributes.Key<Map<String, ?>> ATTR_HEALTH_CHECKING_CONFIG =
117       Attributes.Key.create("internal:health-checking-config");
118   private int recursionCount;
119 
120   /**
121    * Handles newly resolved server groups and metadata attributes from name resolution system.
122    * {@code servers} contained in {@link EquivalentAddressGroup} should be considered equivalent
123    * but may be flattened into a single list if needed.
124    *
125    * <p>Implementations should not modify the given {@code servers}.
126    *
127    * @param resolvedAddresses the resolved server addresses, attributes, and config.
128    * @since 1.21.0
129    */
handleResolvedAddresses(ResolvedAddresses resolvedAddresses)130   public void handleResolvedAddresses(ResolvedAddresses resolvedAddresses) {
131     if (recursionCount++ == 0) {
132       // Note that the information about the addresses actually being accepted will be lost
133       // if you rely on this method for backward compatibility.
134       acceptResolvedAddresses(resolvedAddresses);
135     }
136     recursionCount = 0;
137   }
138 
139   /**
140    * Accepts newly resolved addresses from the name resolution system. The {@link
141    * EquivalentAddressGroup} addresses should be considered equivalent but may be flattened into a
142    * single list if needed.
143    *
144    * <p>Implementations can choose to reject the given addresses by returning {@code false}.
145    *
146    * <p>Implementations should not modify the given {@code addresses}.
147    *
148    * @param resolvedAddresses the resolved server addresses, attributes, and config.
149    * @return {@code true} if the resolved addresses were accepted. {@code false} if rejected.
150    * @since 1.49.0
151    */
acceptResolvedAddresses(ResolvedAddresses resolvedAddresses)152   public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
153     if (resolvedAddresses.getAddresses().isEmpty()
154         && !canHandleEmptyAddressListFromNameResolution()) {
155       handleNameResolutionError(Status.UNAVAILABLE.withDescription(
156           "NameResolver returned no usable address. addrs=" + resolvedAddresses.getAddresses()
157               + ", attrs=" + resolvedAddresses.getAttributes()));
158       return false;
159     } else {
160       if (recursionCount++ == 0) {
161         handleResolvedAddresses(resolvedAddresses);
162       }
163       recursionCount = 0;
164 
165       return true;
166     }
167   }
168 
169   /**
170    * Represents a combination of the resolved server address, associated attributes and a load
171    * balancing policy config.  The config is from the {@link
172    * LoadBalancerProvider#parseLoadBalancingPolicyConfig(Map)}.
173    *
174    * @since 1.21.0
175    */
176   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
177   public static final class ResolvedAddresses {
178     private final List<EquivalentAddressGroup> addresses;
179     @NameResolver.ResolutionResultAttr
180     private final Attributes attributes;
181     @Nullable
182     private final Object loadBalancingPolicyConfig;
183     // Make sure to update toBuilder() below!
184 
ResolvedAddresses( List<EquivalentAddressGroup> addresses, @NameResolver.ResolutionResultAttr Attributes attributes, Object loadBalancingPolicyConfig)185     private ResolvedAddresses(
186         List<EquivalentAddressGroup> addresses,
187         @NameResolver.ResolutionResultAttr Attributes attributes,
188         Object loadBalancingPolicyConfig) {
189       this.addresses =
190           Collections.unmodifiableList(new ArrayList<>(checkNotNull(addresses, "addresses")));
191       this.attributes = checkNotNull(attributes, "attributes");
192       this.loadBalancingPolicyConfig = loadBalancingPolicyConfig;
193     }
194 
195     /**
196      * Factory for constructing a new Builder.
197      *
198      * @since 1.21.0
199      */
newBuilder()200     public static Builder newBuilder() {
201       return new Builder();
202     }
203 
204     /**
205      * Converts this back to a builder.
206      *
207      * @since 1.21.0
208      */
toBuilder()209     public Builder toBuilder() {
210       return newBuilder()
211           .setAddresses(addresses)
212           .setAttributes(attributes)
213           .setLoadBalancingPolicyConfig(loadBalancingPolicyConfig);
214     }
215 
216     /**
217      * Gets the server addresses.
218      *
219      * @since 1.21.0
220      */
getAddresses()221     public List<EquivalentAddressGroup> getAddresses() {
222       return addresses;
223     }
224 
225     /**
226      * Gets the attributes associated with these addresses.  If this was not previously set,
227      * {@link Attributes#EMPTY} will be returned.
228      *
229      * @since 1.21.0
230      */
231     @NameResolver.ResolutionResultAttr
getAttributes()232     public Attributes getAttributes() {
233       return attributes;
234     }
235 
236     /**
237      * Gets the domain specific load balancing policy.  This is the config produced by
238      * {@link LoadBalancerProvider#parseLoadBalancingPolicyConfig(Map)}.
239      *
240      * @since 1.21.0
241      */
242     @Nullable
getLoadBalancingPolicyConfig()243     public Object getLoadBalancingPolicyConfig() {
244       return loadBalancingPolicyConfig;
245     }
246 
247     /**
248      * Builder for {@link ResolvedAddresses}.
249      */
250     @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
251     public static final class Builder {
252       private List<EquivalentAddressGroup> addresses;
253       @NameResolver.ResolutionResultAttr
254       private Attributes attributes = Attributes.EMPTY;
255       @Nullable
256       private Object loadBalancingPolicyConfig;
257 
Builder()258       Builder() {}
259 
260       /**
261        * Sets the addresses.  This field is required.
262        *
263        * @return this.
264        */
setAddresses(List<EquivalentAddressGroup> addresses)265       public Builder setAddresses(List<EquivalentAddressGroup> addresses) {
266         this.addresses = addresses;
267         return this;
268       }
269 
270       /**
271        * Sets the attributes.  This field is optional; if not called, {@link Attributes#EMPTY}
272        * will be used.
273        *
274        * @return this.
275        */
setAttributes(@ameResolver.ResolutionResultAttr Attributes attributes)276       public Builder setAttributes(@NameResolver.ResolutionResultAttr Attributes attributes) {
277         this.attributes = attributes;
278         return this;
279       }
280 
281       /**
282        * Sets the load balancing policy config. This field is optional.
283        *
284        * @return this.
285        */
setLoadBalancingPolicyConfig(@ullable Object loadBalancingPolicyConfig)286       public Builder setLoadBalancingPolicyConfig(@Nullable Object loadBalancingPolicyConfig) {
287         this.loadBalancingPolicyConfig = loadBalancingPolicyConfig;
288         return this;
289       }
290 
291       /**
292        * Constructs the {@link ResolvedAddresses}.
293        */
build()294       public ResolvedAddresses build() {
295         return new ResolvedAddresses(addresses, attributes, loadBalancingPolicyConfig);
296       }
297     }
298 
299     @Override
toString()300     public String toString() {
301       return MoreObjects.toStringHelper(this)
302           .add("addresses", addresses)
303           .add("attributes", attributes)
304           .add("loadBalancingPolicyConfig", loadBalancingPolicyConfig)
305           .toString();
306     }
307 
308     @Override
hashCode()309     public int hashCode() {
310       return Objects.hashCode(addresses, attributes, loadBalancingPolicyConfig);
311     }
312 
313     @Override
equals(Object obj)314     public boolean equals(Object obj) {
315       if (!(obj instanceof ResolvedAddresses)) {
316         return false;
317       }
318       ResolvedAddresses that = (ResolvedAddresses) obj;
319       return Objects.equal(this.addresses, that.addresses)
320           && Objects.equal(this.attributes, that.attributes)
321           && Objects.equal(this.loadBalancingPolicyConfig, that.loadBalancingPolicyConfig);
322     }
323   }
324 
325   /**
326    * Handles an error from the name resolution system.
327    *
328    * @param error a non-OK status
329    * @since 1.2.0
330    */
handleNameResolutionError(Status error)331   public abstract void handleNameResolutionError(Status error);
332 
333   /**
334    * Handles a state change on a Subchannel.
335    *
336    * <p>The initial state of a Subchannel is IDLE. You won't get a notification for the initial IDLE
337    * state.
338    *
339    * <p>If the new state is not SHUTDOWN, this method should create a new picker and call {@link
340    * Helper#updateBalancingState Helper.updateBalancingState()}.  Failing to do so may result in
341    * unnecessary delays of RPCs. Please refer to {@link PickResult#withSubchannel
342    * PickResult.withSubchannel()}'s javadoc for more information.
343    *
344    * <p>SHUTDOWN can only happen in two cases.  One is that LoadBalancer called {@link
345    * Subchannel#shutdown} earlier, thus it should have already discarded this Subchannel.  The other
346    * is that Channel is doing a {@link ManagedChannel#shutdownNow forced shutdown} or has already
347    * terminated, thus there won't be further requests to LoadBalancer.  Therefore, the LoadBalancer
348    * usually don't need to react to a SHUTDOWN state.
349    *
350    * @param subchannel the involved Subchannel
351    * @param stateInfo the new state
352    * @since 1.2.0
353    * @deprecated This method will be removed.  Stop overriding it.  Instead, pass {@link
354    *             SubchannelStateListener} to {@link Subchannel#start} to receive Subchannel state
355    *             updates
356    */
357   @Deprecated
handleSubchannelState( Subchannel subchannel, ConnectivityStateInfo stateInfo)358   public void handleSubchannelState(
359       Subchannel subchannel, ConnectivityStateInfo stateInfo) {
360     // Do nothing.  If the implementation doesn't implement this, it will get subchannel states from
361     // the new API.  We don't throw because there may be forwarding LoadBalancers still plumb this.
362   }
363 
364   /**
365    * The channel asks the load-balancer to shutdown.  No more methods on this class will be called
366    * after this method.  The implementation should shutdown all Subchannels and OOB channels, and do
367    * any other cleanup as necessary.
368    *
369    * @since 1.2.0
370    */
shutdown()371   public abstract void shutdown();
372 
373   /**
374    * Whether this LoadBalancer can handle empty address group list to be passed to {@link
375    * #handleResolvedAddresses(ResolvedAddresses)}.  The default implementation returns
376    * {@code false}, meaning that if the NameResolver returns an empty list, the Channel will turn
377    * that into an error and call {@link #handleNameResolutionError}.  LoadBalancers that want to
378    * accept empty lists should override this method and return {@code true}.
379    *
380    * <p>This method should always return a constant value.  It's not specified when this will be
381    * called.
382    */
canHandleEmptyAddressListFromNameResolution()383   public boolean canHandleEmptyAddressListFromNameResolution() {
384     return false;
385   }
386 
387   /**
388    * The channel asks the LoadBalancer to establish connections now (if applicable) so that the
389    * upcoming RPC may then just pick a ready connection without waiting for connections.  This
390    * is triggered by {@link ManagedChannel#getState ManagedChannel.getState(true)}.
391    *
392    * <p>If LoadBalancer doesn't override it, this is no-op.  If it infeasible to create connections
393    * given the current state, e.g. no Subchannel has been created yet, LoadBalancer can ignore this
394    * request.
395    *
396    * @since 1.22.0
397    */
requestConnection()398   public void requestConnection() {}
399 
400   /**
401    * The main balancing logic.  It <strong>must be thread-safe</strong>. Typically it should only
402    * synchronize on its own state, and avoid synchronizing with the LoadBalancer's state.
403    *
404    * @since 1.2.0
405    */
406   @ThreadSafe
407   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
408   public abstract static class SubchannelPicker {
409     /**
410      * Make a balancing decision for a new RPC.
411      *
412      * @param args the pick arguments
413      * @since 1.3.0
414      */
pickSubchannel(PickSubchannelArgs args)415     public abstract PickResult pickSubchannel(PickSubchannelArgs args);
416 
417     /**
418      * Tries to establish connections now so that the upcoming RPC may then just pick a ready
419      * connection without having to connect first.
420      *
421      * <p>No-op if unsupported.
422      *
423      * @deprecated override {@link LoadBalancer#requestConnection} instead.
424      * @since 1.11.0
425      */
426     @Deprecated
requestConnection()427     public void requestConnection() {}
428   }
429 
430   /**
431    * Provides arguments for a {@link SubchannelPicker#pickSubchannel(
432    * LoadBalancer.PickSubchannelArgs)}.
433    *
434    * @since 1.2.0
435    */
436   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
437   public abstract static class PickSubchannelArgs {
438 
439     /**
440      * Call options.
441      *
442      * @since 1.2.0
443      */
getCallOptions()444     public abstract CallOptions getCallOptions();
445 
446     /**
447      * Headers of the call. {@link SubchannelPicker#pickSubchannel} may mutate it before before
448      * returning.
449      *
450      * @since 1.2.0
451      */
getHeaders()452     public abstract Metadata getHeaders();
453 
454     /**
455      * Call method.
456      *
457      * @since 1.2.0
458      */
getMethodDescriptor()459     public abstract MethodDescriptor<?, ?> getMethodDescriptor();
460   }
461 
462   /**
463    * A balancing decision made by {@link SubchannelPicker SubchannelPicker} for an RPC.
464    *
465    * <p>The outcome of the decision will be one of the following:
466    * <ul>
467    *   <li>Proceed: if a Subchannel is provided via {@link #withSubchannel withSubchannel()}, and is
468    *       in READY state when the RPC tries to start on it, the RPC will proceed on that
469    *       Subchannel.</li>
470    *   <li>Error: if an error is provided via {@link #withError withError()}, and the RPC is not
471    *       wait-for-ready (i.e., {@link CallOptions#withWaitForReady} was not called), the RPC will
472    *       fail immediately with the given error.</li>
473    *   <li>Buffer: in all other cases, the RPC will be buffered in the Channel, until the next
474    *       picker is provided via {@link Helper#updateBalancingState Helper.updateBalancingState()},
475    *       when the RPC will go through the same picking process again.</li>
476    * </ul>
477    *
478    * @since 1.2.0
479    */
480   @Immutable
481   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
482   public static final class PickResult {
483     private static final PickResult NO_RESULT = new PickResult(null, null, Status.OK, false);
484 
485     @Nullable private final Subchannel subchannel;
486     @Nullable private final ClientStreamTracer.Factory streamTracerFactory;
487     // An error to be propagated to the application if subchannel == null
488     // Or OK if there is no error.
489     // subchannel being null and error being OK means RPC needs to wait
490     private final Status status;
491     // True if the result is created by withDrop()
492     private final boolean drop;
493 
PickResult( @ullable Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory, Status status, boolean drop)494     private PickResult(
495         @Nullable Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory,
496         Status status, boolean drop) {
497       this.subchannel = subchannel;
498       this.streamTracerFactory = streamTracerFactory;
499       this.status = checkNotNull(status, "status");
500       this.drop = drop;
501     }
502 
503     /**
504      * A decision to proceed the RPC on a Subchannel.
505      *
506      * <p>The Subchannel should either be an original Subchannel returned by {@link
507      * Helper#createSubchannel Helper.createSubchannel()}, or a wrapper of it preferably based on
508      * {@code ForwardingSubchannel}.  At the very least its {@link Subchannel#getInternalSubchannel
509      * getInternalSubchannel()} must return the same object as the one returned by the original.
510      * Otherwise the Channel cannot use it for the RPC.
511      *
512      * <p>When the RPC tries to use the return Subchannel, which is briefly after this method
513      * returns, the state of the Subchannel will decide where the RPC would go:
514      *
515      * <ul>
516      *   <li>READY: the RPC will proceed on this Subchannel.</li>
517      *   <li>IDLE: the RPC will be buffered.  Subchannel will attempt to create connection.</li>
518      *   <li>All other states: the RPC will be buffered.</li>
519      * </ul>
520      *
521      * <p><strong>All buffered RPCs will stay buffered</strong> until the next call of {@link
522      * Helper#updateBalancingState Helper.updateBalancingState()}, which will trigger a new picking
523      * process.
524      *
525      * <p>Note that Subchannel's state may change at the same time the picker is making the
526      * decision, which means the decision may be made with (to-be) outdated information.  For
527      * example, a picker may return a Subchannel known to be READY, but it has become IDLE when is
528      * about to be used by the RPC, which makes the RPC to be buffered.  The LoadBalancer will soon
529      * learn about the Subchannels' transition from READY to IDLE, create a new picker and allow the
530      * RPC to use another READY transport if there is any.
531      *
532      * <p>You will want to avoid running into a situation where there are READY Subchannels out
533      * there but some RPCs are still buffered for longer than a brief time.
534      * <ul>
535      *   <li>This can happen if you return Subchannels with states other than READY and IDLE.  For
536      *       example, suppose you round-robin on 2 Subchannels, in READY and CONNECTING states
537      *       respectively.  If the picker ignores the state and pick them equally, 50% of RPCs will
538      *       be stuck in buffered state until both Subchannels are READY.</li>
539      *   <li>This can also happen if you don't create a new picker at key state changes of
540      *       Subchannels.  Take the above round-robin example again.  Suppose you do pick only READY
541      *       and IDLE Subchannels, and initially both Subchannels are READY.  Now one becomes IDLE,
542      *       then CONNECTING and stays CONNECTING for a long time.  If you don't create a new picker
543      *       in response to the CONNECTING state to exclude that Subchannel, 50% of RPCs will hit it
544      *       and be buffered even though the other Subchannel is READY.</li>
545      * </ul>
546      *
547      * <p>In order to prevent unnecessary delay of RPCs, the rules of thumb are:
548      * <ol>
549      *   <li>The picker should only pick Subchannels that are known as READY or IDLE.  Whether to
550      *       pick IDLE Subchannels depends on whether you want Subchannels to connect on-demand or
551      *       actively:
552      *       <ul>
553      *         <li>If you want connect-on-demand, include IDLE Subchannels in your pick results,
554      *             because when an RPC tries to use an IDLE Subchannel, the Subchannel will try to
555      *             connect.</li>
556      *         <li>If you want Subchannels to be always connected even when there is no RPC, you
557      *             would call {@link Subchannel#requestConnection Subchannel.requestConnection()}
558      *             whenever the Subchannel has transitioned to IDLE, then you don't need to include
559      *             IDLE Subchannels in your pick results.</li>
560      *       </ul></li>
561      *   <li>Always create a new picker and call {@link Helper#updateBalancingState
562      *       Helper.updateBalancingState()} whenever {@link #handleSubchannelState
563      *       handleSubchannelState()} is called, unless the new state is SHUTDOWN. See
564      *       {@code handleSubchannelState}'s javadoc for more details.</li>
565      * </ol>
566      *
567      * @param subchannel the picked Subchannel.  It must have been {@link Subchannel#start started}
568      * @param streamTracerFactory if not null, will be used to trace the activities of the stream
569      *                            created as a result of this pick. Note it's possible that no
570      *                            stream is created at all in some cases.
571      * @since 1.3.0
572      */
withSubchannel( Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory)573     public static PickResult withSubchannel(
574         Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory) {
575       return new PickResult(
576           checkNotNull(subchannel, "subchannel"), streamTracerFactory, Status.OK,
577           false);
578     }
579 
580     /**
581      * Equivalent to {@code withSubchannel(subchannel, null)}.
582      *
583      * @since 1.2.0
584      */
withSubchannel(Subchannel subchannel)585     public static PickResult withSubchannel(Subchannel subchannel) {
586       return withSubchannel(subchannel, null);
587     }
588 
589     /**
590      * A decision to report a connectivity error to the RPC.  If the RPC is {@link
591      * CallOptions#withWaitForReady wait-for-ready}, it will stay buffered.  Otherwise, it will fail
592      * with the given error.
593      *
594      * @param error the error status.  Must not be OK.
595      * @since 1.2.0
596      */
withError(Status error)597     public static PickResult withError(Status error) {
598       Preconditions.checkArgument(!error.isOk(), "error status shouldn't be OK");
599       return new PickResult(null, null, error, false);
600     }
601 
602     /**
603      * A decision to fail an RPC immediately.  This is a final decision and will ignore retry
604      * policy.
605      *
606      * @param status the status with which the RPC will fail.  Must not be OK.
607      * @since 1.8.0
608      */
withDrop(Status status)609     public static PickResult withDrop(Status status) {
610       Preconditions.checkArgument(!status.isOk(), "drop status shouldn't be OK");
611       return new PickResult(null, null, status, true);
612     }
613 
614     /**
615      * No decision could be made.  The RPC will stay buffered.
616      *
617      * @since 1.2.0
618      */
withNoResult()619     public static PickResult withNoResult() {
620       return NO_RESULT;
621     }
622 
623     /**
624      * The Subchannel if this result was created by {@link #withSubchannel withSubchannel()}, or
625      * null otherwise.
626      *
627      * @since 1.2.0
628      */
629     @Nullable
getSubchannel()630     public Subchannel getSubchannel() {
631       return subchannel;
632     }
633 
634     /**
635      * The stream tracer factory this result was created with.
636      *
637      * @since 1.3.0
638      */
639     @Nullable
getStreamTracerFactory()640     public ClientStreamTracer.Factory getStreamTracerFactory() {
641       return streamTracerFactory;
642     }
643 
644     /**
645      * The status associated with this result.  Non-{@code OK} if created with {@link #withError
646      * withError}, or {@code OK} otherwise.
647      *
648      * @since 1.2.0
649      */
getStatus()650     public Status getStatus() {
651       return status;
652     }
653 
654     /**
655      * Returns {@code true} if this result was created by {@link #withDrop withDrop()}.
656      *
657      * @since 1.8.0
658      */
isDrop()659     public boolean isDrop() {
660       return drop;
661     }
662 
663     @Override
toString()664     public String toString() {
665       return MoreObjects.toStringHelper(this)
666           .add("subchannel", subchannel)
667           .add("streamTracerFactory", streamTracerFactory)
668           .add("status", status)
669           .add("drop", drop)
670           .toString();
671     }
672 
673     @Override
hashCode()674     public int hashCode() {
675       return Objects.hashCode(subchannel, status, streamTracerFactory, drop);
676     }
677 
678     /**
679      * Returns true if the {@link Subchannel}, {@link Status}, and
680      * {@link ClientStreamTracer.Factory} all match.
681      */
682     @Override
equals(Object other)683     public boolean equals(Object other) {
684       if (!(other instanceof PickResult)) {
685         return false;
686       }
687       PickResult that = (PickResult) other;
688       return Objects.equal(subchannel, that.subchannel) && Objects.equal(status, that.status)
689           && Objects.equal(streamTracerFactory, that.streamTracerFactory)
690           && drop == that.drop;
691     }
692   }
693 
694   /**
695    * Arguments for creating a {@link Subchannel}.
696    *
697    * @since 1.22.0
698    */
699   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
700   public static final class CreateSubchannelArgs {
701     private final List<EquivalentAddressGroup> addrs;
702     private final Attributes attrs;
703     private final Object[][] customOptions;
704 
CreateSubchannelArgs( List<EquivalentAddressGroup> addrs, Attributes attrs, Object[][] customOptions)705     private CreateSubchannelArgs(
706         List<EquivalentAddressGroup> addrs, Attributes attrs, Object[][] customOptions) {
707       this.addrs = checkNotNull(addrs, "addresses are not set");
708       this.attrs = checkNotNull(attrs, "attrs");
709       this.customOptions = checkNotNull(customOptions, "customOptions");
710     }
711 
712     /**
713      * Returns the addresses, which is an unmodifiable list.
714      */
getAddresses()715     public List<EquivalentAddressGroup> getAddresses() {
716       return addrs;
717     }
718 
719     /**
720      * Returns the attributes.
721      */
getAttributes()722     public Attributes getAttributes() {
723       return attrs;
724     }
725 
726     /**
727      * Get the value for a custom option or its inherent default.
728      *
729      * @param key Key identifying option
730      */
731     @SuppressWarnings("unchecked")
getOption(Key<T> key)732     public <T> T getOption(Key<T> key) {
733       Preconditions.checkNotNull(key, "key");
734       for (int i = 0; i < customOptions.length; i++) {
735         if (key.equals(customOptions[i][0])) {
736           return (T) customOptions[i][1];
737         }
738       }
739       return key.defaultValue;
740     }
741 
742     /**
743      * Returns a builder with the same initial values as this object.
744      */
toBuilder()745     public Builder toBuilder() {
746       return newBuilder().setAddresses(addrs).setAttributes(attrs).copyCustomOptions(customOptions);
747     }
748 
749     /**
750      * Creates a new builder.
751      */
newBuilder()752     public static Builder newBuilder() {
753       return new Builder();
754     }
755 
756     @Override
toString()757     public String toString() {
758       return MoreObjects.toStringHelper(this)
759           .add("addrs", addrs)
760           .add("attrs", attrs)
761           .add("customOptions", Arrays.deepToString(customOptions))
762           .toString();
763     }
764 
765     @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
766     public static final class Builder {
767 
768       private List<EquivalentAddressGroup> addrs;
769       private Attributes attrs = Attributes.EMPTY;
770       private Object[][] customOptions = new Object[0][2];
771 
Builder()772       Builder() {
773       }
774 
copyCustomOptions(Object[][] options)775       private Builder copyCustomOptions(Object[][] options) {
776         customOptions = new Object[options.length][2];
777         System.arraycopy(options, 0, customOptions, 0, options.length);
778         return this;
779       }
780 
781       /**
782        * Add a custom option. Any existing value for the key is overwritten.
783        *
784        * <p>This is an <strong>optional</strong> property.
785        *
786        * @param key the option key
787        * @param value the option value
788        */
addOption(Key<T> key, T value)789       public <T> Builder addOption(Key<T> key, T value) {
790         Preconditions.checkNotNull(key, "key");
791         Preconditions.checkNotNull(value, "value");
792 
793         int existingIdx = -1;
794         for (int i = 0; i < customOptions.length; i++) {
795           if (key.equals(customOptions[i][0])) {
796             existingIdx = i;
797             break;
798           }
799         }
800 
801         if (existingIdx == -1) {
802           Object[][] newCustomOptions = new Object[customOptions.length + 1][2];
803           System.arraycopy(customOptions, 0, newCustomOptions, 0, customOptions.length);
804           customOptions = newCustomOptions;
805           existingIdx = customOptions.length - 1;
806         }
807         customOptions[existingIdx] = new Object[]{key, value};
808         return this;
809       }
810 
811       /**
812        * The addresses to connect to.  All addresses are considered equivalent and will be tried
813        * in the order they are provided.
814        */
setAddresses(EquivalentAddressGroup addrs)815       public Builder setAddresses(EquivalentAddressGroup addrs) {
816         this.addrs = Collections.singletonList(addrs);
817         return this;
818       }
819 
820       /**
821        * The addresses to connect to.  All addresses are considered equivalent and will
822        * be tried in the order they are provided.
823        *
824        * <p>This is a <strong>required</strong> property.
825        *
826        * @throws IllegalArgumentException if {@code addrs} is empty
827        */
setAddresses(List<EquivalentAddressGroup> addrs)828       public Builder setAddresses(List<EquivalentAddressGroup> addrs) {
829         checkArgument(!addrs.isEmpty(), "addrs is empty");
830         this.addrs = Collections.unmodifiableList(new ArrayList<>(addrs));
831         return this;
832       }
833 
834       /**
835        * Attributes provided here will be included in {@link Subchannel#getAttributes}.
836        *
837        * <p>This is an <strong>optional</strong> property.  Default is empty if not set.
838        */
setAttributes(Attributes attrs)839       public Builder setAttributes(Attributes attrs) {
840         this.attrs = checkNotNull(attrs, "attrs");
841         return this;
842       }
843 
844       /**
845        * Creates a new args object.
846        */
build()847       public CreateSubchannelArgs build() {
848         return new CreateSubchannelArgs(addrs, attrs, customOptions);
849       }
850     }
851 
852     /**
853      * Key for a key-value pair. Uses reference equality.
854      */
855     @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
856     public static final class Key<T> {
857 
858       private final String debugString;
859       private final T defaultValue;
860 
Key(String debugString, T defaultValue)861       private Key(String debugString, T defaultValue) {
862         this.debugString = debugString;
863         this.defaultValue = defaultValue;
864       }
865 
866       /**
867        * Factory method for creating instances of {@link Key}. The default value of the key is
868        * {@code null}.
869        *
870        * @param debugString a debug string that describes this key.
871        * @param <T> Key type
872        * @return Key object
873        */
create(String debugString)874       public static <T> Key<T> create(String debugString) {
875         Preconditions.checkNotNull(debugString, "debugString");
876         return new Key<>(debugString, /*defaultValue=*/ null);
877       }
878 
879       /**
880        * Factory method for creating instances of {@link Key}.
881        *
882        * @param debugString a debug string that describes this key.
883        * @param defaultValue default value to return when value for key not set
884        * @param <T> Key type
885        * @return Key object
886        */
createWithDefault(String debugString, T defaultValue)887       public static <T> Key<T> createWithDefault(String debugString, T defaultValue) {
888         Preconditions.checkNotNull(debugString, "debugString");
889         return new Key<>(debugString, defaultValue);
890       }
891 
892       /**
893        * Returns the user supplied default value for this key.
894        */
getDefault()895       public T getDefault() {
896         return defaultValue;
897       }
898 
899       @Override
toString()900       public String toString() {
901         return debugString;
902       }
903     }
904   }
905 
906   /**
907    * Provides essentials for LoadBalancer implementations.
908    *
909    * @since 1.2.0
910    */
911   @ThreadSafe
912   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
913   public abstract static class Helper {
914     /**
915      * Creates a Subchannel, which is a logical connection to the given group of addresses which are
916      * considered equivalent.  The {@code attrs} are custom attributes associated with this
917      * Subchannel, and can be accessed later through {@link Subchannel#getAttributes
918      * Subchannel.getAttributes()}.
919      *
920      * <p>The LoadBalancer is responsible for closing unused Subchannels, and closing all
921      * Subchannels within {@link #shutdown}.
922      *
923      * <p>It must be called from {@link #getSynchronizationContext the Synchronization Context}
924      *
925      * @since 1.22.0
926      */
createSubchannel(CreateSubchannelArgs args)927     public Subchannel createSubchannel(CreateSubchannelArgs args) {
928       throw new UnsupportedOperationException();
929     }
930 
931     /**
932      * Out-of-band channel for LoadBalancer’s own RPC needs, e.g., talking to an external
933      * load-balancer service.
934      *
935      * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
936      * channels within {@link #shutdown}.
937      *
938      * @since 1.4.0
939      */
createOobChannel(EquivalentAddressGroup eag, String authority)940     public abstract ManagedChannel createOobChannel(EquivalentAddressGroup eag, String authority);
941 
942     /**
943      * Accept a list of EAG for multiple authorities: https://github.com/grpc/grpc-java/issues/4618
944      * */
createOobChannel(List<EquivalentAddressGroup> eag, String authority)945     public ManagedChannel createOobChannel(List<EquivalentAddressGroup> eag,
946         String authority) {
947       throw new UnsupportedOperationException();
948     }
949 
950     /**
951      * Updates the addresses used for connections in the {@code Channel} that was created by {@link
952      * #createOobChannel(EquivalentAddressGroup, String)}. This is superior to {@link
953      * #createOobChannel(EquivalentAddressGroup, String)} when the old and new addresses overlap,
954      * since the channel can continue using an existing connection.
955      *
956      * @throws IllegalArgumentException if {@code channel} was not returned from {@link
957      *     #createOobChannel}
958      * @since 1.4.0
959      */
updateOobChannelAddresses(ManagedChannel channel, EquivalentAddressGroup eag)960     public void updateOobChannelAddresses(ManagedChannel channel, EquivalentAddressGroup eag) {
961       throw new UnsupportedOperationException();
962     }
963 
964     /**
965      * Updates the addresses with a new EAG list. Connection is continued when old and new addresses
966      * overlap.
967      * */
updateOobChannelAddresses(ManagedChannel channel, List<EquivalentAddressGroup> eag)968     public void updateOobChannelAddresses(ManagedChannel channel,
969         List<EquivalentAddressGroup> eag) {
970       throw new UnsupportedOperationException();
971     }
972 
973     /**
974      * Creates an out-of-band channel for LoadBalancer's own RPC needs, e.g., talking to an external
975      * load-balancer service, that is specified by a target string.  See the documentation on
976      * {@link ManagedChannelBuilder#forTarget} for the format of a target string.
977      *
978      * <p>The target string will be resolved by a {@link NameResolver} created according to the
979      * target string.
980      *
981      * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
982      * channels within {@link #shutdown}.
983      *
984      * @since 1.20.0
985      */
createResolvingOobChannel(String target)986     public ManagedChannel createResolvingOobChannel(String target) {
987       return createResolvingOobChannelBuilder(target).build();
988     }
989 
990     /**
991      * Creates an out-of-band channel builder for LoadBalancer's own RPC needs, e.g., talking to an
992      * external load-balancer service, that is specified by a target string.  See the documentation
993      * on {@link ManagedChannelBuilder#forTarget} for the format of a target string.
994      *
995      * <p>The target string will be resolved by a {@link NameResolver} created according to the
996      * target string.
997      *
998      * <p>The returned oob-channel builder defaults to use the same authority and ChannelCredentials
999      * (without bearer tokens) as the parent channel's for authentication. This is different from
1000      * {@link #createResolvingOobChannelBuilder(String, ChannelCredentials)}.
1001      *
1002      * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
1003      * channels within {@link #shutdown}.
1004      *
1005      * @deprecated Use {@link #createResolvingOobChannelBuilder(String, ChannelCredentials)}
1006      *     instead.
1007      * @since 1.31.0
1008      */
1009     @Deprecated
createResolvingOobChannelBuilder(String target)1010     public ManagedChannelBuilder<?> createResolvingOobChannelBuilder(String target) {
1011       throw new UnsupportedOperationException("Not implemented");
1012     }
1013 
1014     /**
1015      * Creates an out-of-band channel builder for LoadBalancer's own RPC needs, e.g., talking to an
1016      * external load-balancer service, that is specified by a target string and credentials.  See
1017      * the documentation on {@link Grpc#newChannelBuilder} for the format of a target string.
1018      *
1019      * <p>The target string will be resolved by a {@link NameResolver} created according to the
1020      * target string.
1021      *
1022      * <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
1023      * channels within {@link #shutdown}.
1024      *
1025      * @since 1.35.0
1026      */
createResolvingOobChannelBuilder( String target, ChannelCredentials creds)1027     public ManagedChannelBuilder<?> createResolvingOobChannelBuilder(
1028         String target, ChannelCredentials creds) {
1029       throw new UnsupportedOperationException();
1030     }
1031 
1032     /**
1033      * Set a new state with a new picker to the channel.
1034      *
1035      * <p>When a new picker is provided via {@code updateBalancingState()}, the channel will apply
1036      * the picker on all buffered RPCs, by calling {@link SubchannelPicker#pickSubchannel(
1037      * LoadBalancer.PickSubchannelArgs)}.
1038      *
1039      * <p>The channel will hold the picker and use it for all RPCs, until {@code
1040      * updateBalancingState()} is called again and a new picker replaces the old one.  If {@code
1041      * updateBalancingState()} has never been called, the channel will buffer all RPCs until a
1042      * picker is provided.
1043      *
1044      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1045      * violated.  It will become an exception eventually.  See <a
1046      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1047      *
1048      * <p>The passed state will be the channel's new state. The SHUTDOWN state should not be passed
1049      * and its behavior is undefined.
1050      *
1051      * @since 1.6.0
1052      */
updateBalancingState( @onnull ConnectivityState newState, @Nonnull SubchannelPicker newPicker)1053     public abstract void updateBalancingState(
1054         @Nonnull ConnectivityState newState, @Nonnull SubchannelPicker newPicker);
1055 
1056     /**
1057      * Call {@link NameResolver#refresh} on the channel's resolver.
1058      *
1059      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1060      * violated.  It will become an exception eventually.  See <a
1061      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1062      *
1063      * @since 1.18.0
1064      */
refreshNameResolution()1065     public void refreshNameResolution() {
1066       throw new UnsupportedOperationException();
1067     }
1068 
1069     /**
1070      * Historically the channel automatically refreshes name resolution if any subchannel
1071      * connection is broken. It's transitioning to let load balancers make the decision. To
1072      * avoid silent breakages, the channel checks if {@link #refreshNameResolution} is called
1073      * by the load balancer. If not, it will do it and log a warning. This will be removed in
1074      * the future and load balancers are completely responsible for triggering the refresh.
1075      * See <a href="https://github.com/grpc/grpc-java/issues/8088">#8088</a> for the background.
1076      *
1077      * <p>This should rarely be used, but sometimes the address for the subchannel wasn't
1078      * provided by the name resolver and a refresh needs to be directed somewhere else instead.
1079      * Then you can call this method to disable the short-tem check for detecting LoadBalancers
1080      * that need to be updated for the new expected behavior.
1081      *
1082      * @since 1.38.0
1083      * @deprecated Warning has been removed
1084      */
1085     @ExperimentalApi("https://github.com/grpc/grpc-java/issues/8088")
1086     @Deprecated
ignoreRefreshNameResolutionCheck()1087     public void ignoreRefreshNameResolutionCheck() {
1088       // no-op
1089     }
1090 
1091     /**
1092      * Returns a {@link SynchronizationContext} that runs tasks in the same Synchronization Context
1093      * as that the callback methods on the {@link LoadBalancer} interface are run in.
1094      *
1095      * <p>Pro-tip: in order to call {@link SynchronizationContext#schedule}, you need to provide a
1096      * {@link ScheduledExecutorService}.  {@link #getScheduledExecutorService} is provided for your
1097      * convenience.
1098      *
1099      * @since 1.17.0
1100      */
getSynchronizationContext()1101     public SynchronizationContext getSynchronizationContext() {
1102       // TODO(zhangkun): make getSynchronizationContext() abstract after runSerialized() is deleted
1103       throw new UnsupportedOperationException();
1104     }
1105 
1106     /**
1107      * Returns a {@link ScheduledExecutorService} for scheduling delayed tasks.
1108      *
1109      * <p>This service is a shared resource and is only meant for quick tasks.  DO NOT block or run
1110      * time-consuming tasks.
1111      *
1112      * <p>The returned service doesn't support {@link ScheduledExecutorService#shutdown shutdown()}
1113      * and {@link ScheduledExecutorService#shutdownNow shutdownNow()}.  They will throw if called.
1114      *
1115      * @since 1.17.0
1116      */
getScheduledExecutorService()1117     public ScheduledExecutorService getScheduledExecutorService() {
1118       throw new UnsupportedOperationException();
1119     }
1120 
1121     /**
1122      * Returns the authority string of the channel, which is derived from the DNS-style target name.
1123      * If overridden by a load balancer, {@link #getUnsafeChannelCredentials} must also be
1124      * overridden to call {@link #getChannelCredentials} or provide appropriate credentials.
1125      *
1126      * @since 1.2.0
1127      */
getAuthority()1128     public abstract String getAuthority();
1129 
1130     /**
1131      * Returns the ChannelCredentials used to construct the channel, without bearer tokens.
1132      *
1133      * @since 1.35.0
1134      */
getChannelCredentials()1135     public ChannelCredentials getChannelCredentials() {
1136       return getUnsafeChannelCredentials().withoutBearerTokens();
1137     }
1138 
1139     /**
1140      * Returns the UNSAFE ChannelCredentials used to construct the channel,
1141      * including bearer tokens. Load balancers should generally have no use for
1142      * these credentials and use of them is heavily discouraged. These must be used
1143      * <em>very</em> carefully to avoid sending bearer tokens to untrusted servers
1144      * as the server could then impersonate the client. Generally it is only safe
1145      * to use these credentials when communicating with the backend.
1146      *
1147      * @since 1.35.0
1148      */
getUnsafeChannelCredentials()1149     public ChannelCredentials getUnsafeChannelCredentials() {
1150       throw new UnsupportedOperationException();
1151     }
1152 
1153     /**
1154      * Returns the {@link ChannelLogger} for the Channel served by this LoadBalancer.
1155      *
1156      * @since 1.17.0
1157      */
getChannelLogger()1158     public ChannelLogger getChannelLogger() {
1159       throw new UnsupportedOperationException();
1160     }
1161 
1162     /**
1163      * Returns the {@link NameResolver.Args} that the Channel uses to create {@link NameResolver}s.
1164      *
1165      * @since 1.22.0
1166      */
getNameResolverArgs()1167     public NameResolver.Args getNameResolverArgs() {
1168       throw new UnsupportedOperationException();
1169     }
1170 
1171     /**
1172      * Returns the {@link NameResolverRegistry} that the Channel uses to look for {@link
1173      * NameResolver}s.
1174      *
1175      * @since 1.22.0
1176      */
getNameResolverRegistry()1177     public NameResolverRegistry getNameResolverRegistry() {
1178       throw new UnsupportedOperationException();
1179     }
1180   }
1181 
1182   /**
1183    * A logical connection to a server, or a group of equivalent servers represented by an {@link
1184    * EquivalentAddressGroup}.
1185    *
1186    * <p>It maintains at most one physical connection (aka transport) for sending new RPCs, while
1187    * also keeps track of previous transports that has been shut down but not terminated yet.
1188    *
1189    * <p>If there isn't an active transport yet, and an RPC is assigned to the Subchannel, it will
1190    * create a new transport.  It won't actively create transports otherwise.  {@link
1191    * #requestConnection requestConnection()} can be used to ask Subchannel to create a transport if
1192    * there isn't any.
1193    *
1194    * <p>{@link #start} must be called prior to calling any other methods, with the exception of
1195    * {@link #shutdown}, which can be called at any time.
1196    *
1197    * @since 1.2.0
1198    */
1199   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
1200   public abstract static class Subchannel {
1201     /**
1202      * Starts the Subchannel.  Can only be called once.
1203      *
1204      * <p>Must be called prior to any other method on this class, except for {@link #shutdown} which
1205      * may be called at any time.
1206      *
1207      * <p>Must be called from the {@link Helper#getSynchronizationContext Synchronization Context},
1208      * otherwise it may throw.  See <a href="https://github.com/grpc/grpc-java/issues/5015">
1209      * #5015</a> for more discussions.
1210      *
1211      * @param listener receives state updates for this Subchannel.
1212      */
start(SubchannelStateListener listener)1213     public void start(SubchannelStateListener listener) {
1214       throw new UnsupportedOperationException("Not implemented");
1215     }
1216 
1217     /**
1218      * Shuts down the Subchannel.  After this method is called, this Subchannel should no longer
1219      * be returned by the latest {@link SubchannelPicker picker}, and can be safely discarded.
1220      *
1221      * <p>Calling it on an already shut-down Subchannel has no effect.
1222      *
1223      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1224      * violated.  It will become an exception eventually.  See <a
1225      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1226      *
1227      * @since 1.2.0
1228      */
shutdown()1229     public abstract void shutdown();
1230 
1231     /**
1232      * Asks the Subchannel to create a connection (aka transport), if there isn't an active one.
1233      *
1234      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1235      * violated.  It will become an exception eventually.  See <a
1236      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1237      *
1238      * @since 1.2.0
1239      */
requestConnection()1240     public abstract void requestConnection();
1241 
1242     /**
1243      * Returns the addresses that this Subchannel is bound to.  This can be called only if
1244      * the Subchannel has only one {@link EquivalentAddressGroup}.  Under the hood it calls
1245      * {@link #getAllAddresses}.
1246      *
1247      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1248      * violated.  It will become an exception eventually.  See <a
1249      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1250      *
1251      * @throws IllegalStateException if this subchannel has more than one EquivalentAddressGroup.
1252      *         Use {@link #getAllAddresses} instead
1253      * @since 1.2.0
1254      */
getAddresses()1255     public final EquivalentAddressGroup getAddresses() {
1256       List<EquivalentAddressGroup> groups = getAllAddresses();
1257       Preconditions.checkState(groups.size() == 1, "%s does not have exactly one group", groups);
1258       return groups.get(0);
1259     }
1260 
1261     /**
1262      * Returns the addresses that this Subchannel is bound to. The returned list will not be empty.
1263      *
1264      * <p>It should be called from the Synchronization Context.  Currently will log a warning if
1265      * violated.  It will become an exception eventually.  See <a
1266      * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for the background.
1267      *
1268      * @since 1.14.0
1269      */
getAllAddresses()1270     public List<EquivalentAddressGroup> getAllAddresses() {
1271       throw new UnsupportedOperationException();
1272     }
1273 
1274     /**
1275      * The same attributes passed to {@link Helper#createSubchannel Helper.createSubchannel()}.
1276      * LoadBalancer can use it to attach additional information here, e.g., the shard this
1277      * Subchannel belongs to.
1278      *
1279      * @since 1.2.0
1280      */
getAttributes()1281     public abstract Attributes getAttributes();
1282 
1283     /**
1284      * (Internal use only) returns a {@link Channel} that is backed by this Subchannel.  This allows
1285      * a LoadBalancer to issue its own RPCs for auxiliary purposes, such as health-checking, on
1286      * already-established connections.  This channel has certain restrictions:
1287      * <ol>
1288      *   <li>It can issue RPCs only if the Subchannel is {@code READY}. If {@link
1289      *   Channel#newCall} is called when the Subchannel is not {@code READY}, the RPC will fail
1290      *   immediately.</li>
1291      *   <li>It doesn't support {@link CallOptions#withWaitForReady wait-for-ready} RPCs. Such RPCs
1292      *   will fail immediately.</li>
1293      * </ol>
1294      *
1295      * <p>RPCs made on this Channel is not counted when determining ManagedChannel's {@link
1296      * ManagedChannelBuilder#idleTimeout idle mode}.  In other words, they won't prevent
1297      * ManagedChannel from entering idle mode.
1298      *
1299      * <p>Warning: RPCs made on this channel will prevent a shut-down transport from terminating. If
1300      * you make long-running RPCs, you need to make sure they will finish in time after the
1301      * Subchannel has transitioned away from {@code READY} state
1302      * (notified through {@link #handleSubchannelState}).
1303      *
1304      * <p>Warning: this is INTERNAL API, is not supposed to be used by external users, and may
1305      * change without notice. If you think you must use it, please file an issue.
1306      */
1307     @Internal
asChannel()1308     public Channel asChannel() {
1309       throw new UnsupportedOperationException();
1310     }
1311 
1312     /**
1313      * Returns a {@link ChannelLogger} for this Subchannel.
1314      *
1315      * @since 1.17.0
1316      */
getChannelLogger()1317     public ChannelLogger getChannelLogger() {
1318       throw new UnsupportedOperationException();
1319     }
1320 
1321     /**
1322      * Replaces the existing addresses used with this {@code Subchannel}. If the new and old
1323      * addresses overlap, the Subchannel can continue using an existing connection.
1324      *
1325      * <p>It must be called from the Synchronization Context or will throw.
1326      *
1327      * @throws IllegalArgumentException if {@code addrs} is empty
1328      * @since 1.22.0
1329      */
updateAddresses(List<EquivalentAddressGroup> addrs)1330     public void updateAddresses(List<EquivalentAddressGroup> addrs) {
1331       throw new UnsupportedOperationException();
1332     }
1333 
1334     /**
1335      * (Internal use only) returns an object that represents the underlying subchannel that is used
1336      * by the Channel for sending RPCs when this {@link Subchannel} is picked.  This is an opaque
1337      * object that is both provided and consumed by the Channel.  Its type <strong>is not</strong>
1338      * {@code Subchannel}.
1339      *
1340      * <p>Warning: this is INTERNAL API, is not supposed to be used by external users, and may
1341      * change without notice. If you think you must use it, please file an issue and we can consider
1342      * removing its "internal" status.
1343      */
1344     @Internal
getInternalSubchannel()1345     public Object getInternalSubchannel() {
1346       throw new UnsupportedOperationException();
1347     }
1348   }
1349 
1350   /**
1351    * Receives state changes for one {@link Subchannel}. All methods are run under {@link
1352    * Helper#getSynchronizationContext}.
1353    *
1354    * @since 1.22.0
1355    */
1356   public interface SubchannelStateListener {
1357     /**
1358      * Handles a state change on a Subchannel.
1359      *
1360      * <p>The initial state of a Subchannel is IDLE. You won't get a notification for the initial
1361      * IDLE state.
1362      *
1363      * <p>If the new state is not SHUTDOWN, this method should create a new picker and call {@link
1364      * Helper#updateBalancingState Helper.updateBalancingState()}.  Failing to do so may result in
1365      * unnecessary delays of RPCs. Please refer to {@link PickResult#withSubchannel
1366      * PickResult.withSubchannel()}'s javadoc for more information.
1367      *
1368      * <p>When a subchannel's state is IDLE or TRANSIENT_FAILURE and the address for the subchannel
1369      * was received in {@link LoadBalancer#handleResolvedAddresses}, load balancers should call
1370      * {@link Helper#refreshNameResolution} to inform polling name resolvers that it is an
1371      * appropriate time to refresh the addresses. Without the refresh, changes to the addresses may
1372      * never be detected.
1373      *
1374      * <p>SHUTDOWN can only happen in two cases.  One is that LoadBalancer called {@link
1375      * Subchannel#shutdown} earlier, thus it should have already discarded this Subchannel.  The
1376      * other is that Channel is doing a {@link ManagedChannel#shutdownNow forced shutdown} or has
1377      * already terminated, thus there won't be further requests to LoadBalancer.  Therefore, the
1378      * LoadBalancer usually don't need to react to a SHUTDOWN state.
1379      *
1380      * @param newState the new state
1381      * @since 1.22.0
1382      */
onSubchannelState(ConnectivityStateInfo newState)1383     void onSubchannelState(ConnectivityStateInfo newState);
1384   }
1385 
1386   /**
1387    * Factory to create {@link LoadBalancer} instance.
1388    *
1389    * @since 1.2.0
1390    */
1391   @ThreadSafe
1392   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
1393   public abstract static class Factory {
1394     /**
1395      * Creates a {@link LoadBalancer} that will be used inside a channel.
1396      *
1397      * @since 1.2.0
1398      */
newLoadBalancer(Helper helper)1399     public abstract LoadBalancer newLoadBalancer(Helper helper);
1400   }
1401 }
1402