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