1616
1717package io .grpc ;
1818
19- import static com .google .common .base .Preconditions .checkArgument ;
2019import static com .google .common .base .Preconditions .checkNotNull ;
2120
2221import com .google .common .base .MoreObjects ;
2322import com .google .common .base .Objects ;
2423import com .google .common .base .Preconditions ;
2524import java .util .ArrayList ;
26- import java .util .Arrays ;
2725import java .util .Collections ;
2826import java .util .List ;
2927import java .util .Map ;
@@ -337,16 +335,9 @@ public boolean equals(Object obj) {
337335 * @param subchannel the involved Subchannel
338336 * @param stateInfo the new state
339337 * @since 1.2.0
340- * @deprecated This method will be removed. Stop overriding it. Instead, pass {@link
341- * SubchannelStateListener} to {@link Helper#createSubchannel(CreateSubchannelArgs)}
342- * to receive Subchannel state updates
343338 */
344- @ Deprecated
345- public void handleSubchannelState (
346- Subchannel subchannel , ConnectivityStateInfo stateInfo ) {
347- // Do nothing. If the implemetation doesn't implement this, it will get subchannel states from
348- // the new API. We don't throw because there may be forwarding LoadBalancers still plumb this.
349- }
339+ public abstract void handleSubchannelState (
340+ Subchannel subchannel , ConnectivityStateInfo stateInfo );
350341
351342 /**
352343 * The channel asks the load-balancer to shutdown. No more callbacks will be called after this
@@ -660,243 +651,6 @@ public boolean equals(Object other) {
660651 }
661652 }
662653
663- /**
664- * Arguments for {@link Helper#createSubchannel(CreateSubchannelArgs)}.
665- *
666- * @since 1.21.0
667- */
668- @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/1771" )
669- public static final class CreateSubchannelArgs {
670- private final List <EquivalentAddressGroup > addrs ;
671- private final Attributes attrs ;
672- private final SubchannelStateListener stateListener ;
673- private final Object [][] customOptions ;
674-
675- private CreateSubchannelArgs (
676- List <EquivalentAddressGroup > addrs , Attributes attrs , Object [][] customOptions ,
677- SubchannelStateListener stateListener ) {
678- this .addrs = checkNotNull (addrs , "addresses are not set" );
679- this .attrs = checkNotNull (attrs , "attrs" );
680- this .customOptions = checkNotNull (customOptions , "customOptions" );
681- this .stateListener = checkNotNull (stateListener , "SubchannelStateListener is not set" );
682- }
683-
684- /**
685- * Returns the addresses, which is an unmodifiable list.
686- */
687- public List <EquivalentAddressGroup > getAddresses () {
688- return addrs ;
689- }
690-
691- /**
692- * Returns the attributes.
693- */
694- public Attributes getAttributes () {
695- return attrs ;
696- }
697-
698- /**
699- * Get the value for a custom option or its inherent default.
700- *
701- * @param key Key identifying option
702- */
703- @ SuppressWarnings ("unchecked" )
704- public <T > T getOption (Key <T > key ) {
705- Preconditions .checkNotNull (key , "key" );
706- for (int i = 0 ; i < customOptions .length ; i ++) {
707- if (key .equals (customOptions [i ][0 ])) {
708- return (T ) customOptions [i ][1 ];
709- }
710- }
711- return key .defaultValue ;
712- }
713-
714- /**
715- * Returns the state listener.
716- */
717- public SubchannelStateListener getStateListener () {
718- return stateListener ;
719- }
720-
721- /**
722- * Returns a builder with the same initial values as this object.
723- */
724- public Builder toBuilder () {
725- return newBuilder ().setAddresses (addrs ).setAttributes (attrs ).setStateListener (stateListener )
726- .copyCustomOptions (customOptions );
727- }
728-
729- /**
730- * Creates a new builder.
731- */
732- public static Builder newBuilder () {
733- return new Builder ();
734- }
735-
736- @ Override
737- public String toString () {
738- return MoreObjects .toStringHelper (this )
739- .add ("addrs" , addrs )
740- .add ("attrs" , attrs )
741- .add ("listener" , stateListener )
742- .add ("customOptions" , Arrays .deepToString (customOptions ))
743- .toString ();
744- }
745-
746- @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/1771" )
747- public static final class Builder {
748-
749- private List <EquivalentAddressGroup > addrs ;
750- private Attributes attrs = Attributes .EMPTY ;
751- private SubchannelStateListener stateListener ;
752- private Object [][] customOptions = new Object [0 ][2 ];
753-
754- Builder () {
755- }
756-
757- private <T > Builder copyCustomOptions (Object [][] options ) {
758- customOptions = new Object [options .length ][2 ];
759- System .arraycopy (options , 0 , customOptions , 0 , options .length );
760- return this ;
761- }
762-
763- /**
764- * Add a custom option. Any existing value for the key is overwritten.
765- *
766- * <p>This is an <strong>optional</strong> property.
767- *
768- * @param key the option key
769- * @param value the option value
770- */
771- public <T > Builder addOption (Key <T > key , T value ) {
772- Preconditions .checkNotNull (key , "key" );
773- Preconditions .checkNotNull (value , "value" );
774-
775- int existingIdx = -1 ;
776- for (int i = 0 ; i < customOptions .length ; i ++) {
777- if (key .equals (customOptions [i ][0 ])) {
778- existingIdx = i ;
779- break ;
780- }
781- }
782-
783- if (existingIdx == -1 ) {
784- Object [][] newCustomOptions = new Object [customOptions .length + 1 ][2 ];
785- System .arraycopy (customOptions , 0 , newCustomOptions , 0 , customOptions .length );
786- customOptions = newCustomOptions ;
787- existingIdx = customOptions .length - 1 ;
788- }
789- customOptions [existingIdx ] = new Object []{key , value };
790- return this ;
791- }
792-
793- /**
794- * The addresses to connect to. All addresses are considered equivalent and will be tried
795- * in the order they are provided.
796- */
797- public Builder setAddresses (EquivalentAddressGroup addrs ) {
798- this .addrs = Collections .singletonList (addrs );
799- return this ;
800- }
801-
802- /**
803- * The addresses to connect to. All addresses are considered equivalent and will
804- * be tried in the order they are provided.
805- *
806- * <p>This is a <strong>required</strong> property.
807- *
808- * @throws IllegalArgumentException if {@code addrs} is empty
809- */
810- public Builder setAddresses (List <EquivalentAddressGroup > addrs ) {
811- checkArgument (!addrs .isEmpty (), "addrs is empty" );
812- this .addrs = Collections .unmodifiableList (new ArrayList <>(addrs ));
813- return this ;
814- }
815-
816- /**
817- * Attributes provided here will be included in {@link Subchannel#getAttributes}.
818- *
819- * <p>This is an <strong>optional</strong> property. Default is empty if not set.
820- */
821- public Builder setAttributes (Attributes attrs ) {
822- this .attrs = checkNotNull (attrs , "attrs" );
823- return this ;
824- }
825-
826- /**
827- * Receives state changes of the created Subchannel. The listener is called from
828- * the {@link Helper#getSynchronizationContext Synchronization Context}. It's safe to share
829- * the listener among multiple Subchannels.
830- *
831- * <p>This is a <strong>required</strong> property.
832- */
833- public Builder setStateListener (SubchannelStateListener listener ) {
834- this .stateListener = checkNotNull (listener , "listener" );
835- return this ;
836- }
837-
838- /**
839- * Creates a new args object.
840- */
841- public CreateSubchannelArgs build () {
842- return new CreateSubchannelArgs (addrs , attrs , customOptions , stateListener );
843- }
844- }
845-
846- /**
847- * Key for a key-value pair. Uses reference equality.
848- */
849- @ ExperimentalApi ("https://github.com/grpc/grpc-java/issues/1771" )
850- public static final class Key <T > {
851-
852- private final String debugString ;
853- private final T defaultValue ;
854-
855- private Key (String debugString , T defaultValue ) {
856- this .debugString = debugString ;
857- this .defaultValue = defaultValue ;
858- }
859-
860- /**
861- * Factory method for creating instances of {@link Key}. The default value of the key is
862- * {@code null}.
863- *
864- * @param debugString a debug string that describes this key.
865- * @param <T> Key type
866- * @return Key object
867- */
868- public static <T > Key <T > create (String debugString ) {
869- Preconditions .checkNotNull (debugString , "debugString" );
870- return new Key <>(debugString , /*defaultValue=*/ null );
871- }
872-
873- /**
874- * Factory method for creating instances of {@link Key}.
875- *
876- * @param debugString a debug string that describes this key.
877- * @param defaultValue default value to return when value for key not set
878- * @param <T> Key type
879- * @return Key object
880- */
881- public static <T > Key <T > createWithDefault (String debugString , T defaultValue ) {
882- Preconditions .checkNotNull (debugString , "debugString" );
883- return new Key <>(debugString , defaultValue );
884- }
885-
886- /**
887- * Returns the user supplied default value for this key.
888- */
889- public T getDefault () {
890- return defaultValue ;
891- }
892-
893- @ Override
894- public String toString () {
895- return debugString ;
896- }
897- }
898- }
899-
900654 /**
901655 * Provides essentials for LoadBalancer implementations.
902656 *
@@ -910,11 +664,7 @@ public abstract static class Helper {
910664 * EquivalentAddressGroup}.
911665 *
912666 * @since 1.2.0
913- * @deprecated Use {@link #createSubchannel(CreateSubchannelArgs)} instead. Note the new API
914- * must be called from {@link #getSynchronizationContext the Synchronization
915- * Context}.
916667 */
917- @ Deprecated
918668 public final Subchannel createSubchannel (EquivalentAddressGroup addrs , Attributes attrs ) {
919669 checkNotNull (addrs , "addrs" );
920670 return createSubchannel (Collections .singletonList (addrs ), attrs );
@@ -935,35 +685,11 @@ public final Subchannel createSubchannel(EquivalentAddressGroup addrs, Attribute
935685 *
936686 * @throws IllegalArgumentException if {@code addrs} is empty
937687 * @since 1.14.0
938- * @deprecated Use {@link #createSubchannel(CreateSubchannelArgs)} instead. Note the new API
939- * must be called from {@link #getSynchronizationContext the Synchronization
940- * Context}.
941688 */
942- @ Deprecated
943689 public Subchannel createSubchannel (List <EquivalentAddressGroup > addrs , Attributes attrs ) {
944690 throw new UnsupportedOperationException ();
945691 }
946692
947- /**
948- * Creates a Subchannel, which is a logical connection to the given group of addresses which are
949- * considered equivalent. The {@code attrs} are custom attributes associated with this
950- * Subchannel, and can be accessed later through {@link Subchannel#getAttributes
951- * Subchannel.getAttributes()}.
952- *
953- * <p>This method <strong>must be called from the {@link #getSynchronizationContext
954- * Synchronization Context}</strong>, otherwise it may throw. This is to avoid the race between
955- * the caller and {@link SubchannelStateListener#onSubchannelState}. See <a
956- * href="https://github.com/grpc/grpc-java/issues/5015">#5015</a> for more discussions.
957- *
958- * <p>The LoadBalancer is responsible for closing unused Subchannels, and closing all
959- * Subchannels within {@link #shutdown}.
960- *
961- * @since 1.21.0
962- */
963- public Subchannel createSubchannel (CreateSubchannelArgs args ) {
964- throw new UnsupportedOperationException ();
965- }
966-
967693 /**
968694 * Equivalent to {@link #updateSubchannelAddresses(io.grpc.LoadBalancer.Subchannel, List)} with
969695 * the given single {@code EquivalentAddressGroup}.
@@ -1180,7 +906,7 @@ public abstract static class Subchannel {
1180906 */
1181907 public final EquivalentAddressGroup getAddresses () {
1182908 List <EquivalentAddressGroup > groups = getAllAddresses ();
1183- Preconditions .checkState (groups .size () == 1 , "%s does not have exactly one group" , groups );
909+ Preconditions .checkState (groups .size () == 1 , "Does not have exactly one group" );
1184910 return groups .get (0 );
1185911 }
1186912
@@ -1241,39 +967,6 @@ public ChannelLogger getChannelLogger() {
1241967 }
1242968 }
1243969
1244- /**
1245- * Receives state changes for one or more {@link Subchannel}s. All methods are run under {@link
1246- * Helper#getSynchronizationContext}.
1247- *
1248- * @since 1.21.0
1249- */
1250- public interface SubchannelStateListener {
1251-
1252- /**
1253- * Handles a state change on a Subchannel.
1254- *
1255- * <p>The initial state of a Subchannel is IDLE. You won't get a notification for the initial
1256- * IDLE state.
1257- *
1258- * <p>If the new state is not SHUTDOWN, this method should create a new picker and call {@link
1259- * Helper#updateBalancingState Helper.updateBalancingState()}. Failing to do so may result in
1260- * unnecessary delays of RPCs. Please refer to {@link PickResult#withSubchannel
1261- * PickResult.withSubchannel()}'s javadoc for more information.
1262- *
1263- * <p>SHUTDOWN can only happen in two cases. One is that LoadBalancer called {@link
1264- * Subchannel#shutdown} earlier, thus it should have already discarded this Subchannel. The
1265- * other is that Channel is doing a {@link ManagedChannel#shutdownNow forced shutdown} or has
1266- * already terminated, thus there won't be further requests to LoadBalancer. Therefore,
1267- * SHUTDOWN can be safely ignored.
1268- *
1269- * @param subchannel the involved Subchannel
1270- * @param newState the new state
1271- *
1272- * @since 1.21.0
1273- */
1274- void onSubchannelState (Subchannel subchannel , ConnectivityStateInfo newState );
1275- }
1276-
1277970 /**
1278971 * Factory to create {@link LoadBalancer} instance.
1279972 *
0 commit comments