grpc 1.32.0 → 1.33.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +175 -376
  3. data/include/grpc/grpc.h +0 -5
  4. data/include/grpc/grpc_security.h +16 -0
  5. data/include/grpc/impl/codegen/grpc_types.h +0 -5
  6. data/src/core/ext/filters/client_channel/client_channel.cc +204 -170
  7. data/src/core/ext/filters/client_channel/config_selector.cc +0 -4
  8. data/src/core/ext/filters/client_channel/config_selector.h +34 -5
  9. data/src/core/ext/filters/client_channel/lb_policy.h +1 -1
  10. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +48 -35
  11. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +7 -5
  12. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +3 -2
  13. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +106 -106
  14. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +2 -2
  15. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +3 -3
  16. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +3 -3
  17. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +9 -32
  18. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -3
  19. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +198 -126
  20. data/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc +439 -249
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/eds_drop.cc +571 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +727 -0
  23. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +8 -1
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +1 -1
  25. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +553 -358
  26. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h +28 -0
  27. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -39
  28. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +4 -2
  29. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +44 -43
  30. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +5 -9
  31. data/src/core/ext/filters/client_channel/server_address.cc +80 -0
  32. data/src/core/ext/filters/client_channel/server_address.h +25 -36
  33. data/src/core/ext/filters/client_channel/service_config.cc +16 -13
  34. data/src/core/ext/filters/client_channel/service_config.h +7 -4
  35. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -2
  36. data/src/core/ext/filters/client_channel/service_config_parser.cc +8 -6
  37. data/src/core/ext/filters/client_channel/service_config_parser.h +8 -5
  38. data/src/core/ext/filters/client_channel/subchannel_interface.h +44 -0
  39. data/src/core/ext/filters/message_size/message_size_filter.cc +2 -1
  40. data/src/core/ext/filters/message_size/message_size_filter.h +2 -1
  41. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +17 -10
  42. data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -2
  43. data/src/core/ext/transport/chttp2/transport/flow_control.h +10 -0
  44. data/src/core/ext/transport/chttp2/transport/internal.h +5 -0
  45. data/src/core/ext/transport/chttp2/transport/parsing.cc +16 -2
  46. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c +29 -9
  47. data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h +66 -0
  48. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +123 -45
  49. data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +310 -53
  50. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +17 -5
  51. data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +45 -0
  52. data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +1 -0
  53. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c +16 -9
  54. data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h +38 -15
  55. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c +53 -0
  56. data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h +133 -0
  57. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c +54 -8
  58. data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h +123 -5
  59. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +40 -16
  60. data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +114 -5
  61. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +36 -0
  62. data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h +85 -0
  63. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +36 -16
  64. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +86 -20
  65. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +23 -6
  66. data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +54 -5
  67. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +10 -6
  68. data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +28 -11
  69. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +184 -57
  70. data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +504 -69
  71. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c +6 -5
  72. data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h +11 -7
  73. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +78 -26
  74. data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +236 -25
  75. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +8 -9
  76. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +19 -33
  77. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c +7 -3
  78. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +16 -0
  79. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +65 -23
  80. data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +229 -47
  81. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +20 -10
  82. data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +67 -4
  83. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c +3 -2
  84. data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h +6 -0
  85. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c +242 -0
  86. data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h +753 -0
  87. data/src/core/ext/upb-generated/udpa/annotations/security.upb.c +31 -0
  88. data/src/core/ext/upb-generated/udpa/annotations/security.upb.h +57 -0
  89. data/src/core/ext/upb-generated/udpa/core/v1/authority.upb.c +28 -0
  90. data/src/core/ext/upb-generated/udpa/core/v1/authority.upb.h +53 -0
  91. data/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c +52 -0
  92. data/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.h +129 -0
  93. data/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c +42 -0
  94. data/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.h +77 -0
  95. data/src/core/ext/upb-generated/udpa/core/v1/resource.upb.c +36 -0
  96. data/src/core/ext/upb-generated/udpa/core/v1/resource.upb.h +85 -0
  97. data/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c +54 -0
  98. data/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.h +160 -0
  99. data/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c +36 -0
  100. data/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.h +84 -0
  101. data/src/core/ext/xds/certificate_provider_factory.h +59 -0
  102. data/src/core/ext/xds/certificate_provider_registry.cc +103 -0
  103. data/src/core/ext/xds/certificate_provider_registry.h +57 -0
  104. data/src/core/ext/xds/certificate_provider_store.h +50 -0
  105. data/src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc +377 -0
  106. data/src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h +102 -0
  107. data/src/core/ext/xds/xds_api.cc +301 -93
  108. data/src/core/ext/xds/xds_api.h +129 -92
  109. data/src/core/ext/xds/xds_channel_args.h +6 -3
  110. data/src/core/ext/xds/xds_client.cc +498 -410
  111. data/src/core/ext/xds/xds_client.h +105 -51
  112. data/src/core/ext/xds/xds_client_stats.cc +18 -12
  113. data/src/core/ext/xds/xds_client_stats.h +33 -5
  114. data/src/core/lib/channel/channel_args.h +0 -1
  115. data/src/core/lib/channel/channelz.cc +10 -45
  116. data/src/core/lib/channel/channelz.h +11 -19
  117. data/src/core/lib/channel/channelz_registry.cc +12 -11
  118. data/src/core/lib/channel/channelz_registry.h +3 -0
  119. data/src/core/lib/gpr/time_precise.cc +2 -0
  120. data/src/core/lib/gpr/time_precise.h +6 -2
  121. data/src/core/lib/gprpp/dual_ref_counted.h +336 -0
  122. data/src/core/lib/gprpp/ref_counted.h +51 -22
  123. data/src/core/lib/gprpp/ref_counted_ptr.h +153 -0
  124. data/src/core/lib/iomgr/endpoint_cfstream.cc +9 -5
  125. data/src/core/lib/iomgr/exec_ctx.h +10 -8
  126. data/src/core/lib/json/json_util.cc +58 -0
  127. data/src/core/lib/json/json_util.h +37 -0
  128. data/src/core/lib/security/certificate_provider.h +60 -0
  129. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +321 -0
  130. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +214 -0
  131. data/src/core/lib/security/credentials/xds/xds_credentials.cc +45 -0
  132. data/src/core/lib/security/credentials/xds/xds_credentials.h +51 -0
  133. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +6 -10
  134. data/src/core/lib/security/security_connector/ssl_utils.h +5 -0
  135. data/src/core/lib/surface/channel.cc +9 -31
  136. data/src/core/lib/surface/channel.h +6 -1
  137. data/src/core/lib/surface/init.cc +26 -9
  138. data/src/core/lib/surface/version.cc +2 -2
  139. data/src/core/lib/transport/bdp_estimator.h +2 -1
  140. data/src/core/lib/transport/connectivity_state.h +2 -2
  141. data/src/core/lib/transport/metadata.cc +11 -1
  142. data/src/core/plugin_registry/grpc_plugin_registry.cc +35 -20
  143. data/src/core/tsi/ssl_transport_security.cc +2 -2
  144. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -2
  145. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -3
  146. data/src/ruby/lib/grpc/version.rb +1 -1
  147. data/third_party/boringssl-with-bazel/err_data.c +465 -463
  148. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +0 -6
  149. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +9 -43
  150. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa_asn1.c +55 -4
  151. data/third_party/boringssl-with-bazel/src/crypto/dsa/internal.h +34 -0
  152. data/third_party/boringssl-with-bazel/src/crypto/evp/evp.c +4 -0
  153. data/third_party/boringssl-with-bazel/src/crypto/evp/p_dsa_asn1.c +6 -2
  154. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.c +2 -0
  155. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h +4 -0
  156. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c +30 -10
  157. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c +10 -15
  158. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +98 -11
  159. data/third_party/boringssl-with-bazel/src/crypto/hpke/internal.h +51 -6
  160. data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +44 -2
  161. data/third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c +221 -49
  162. data/third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c +64 -20
  163. data/third_party/boringssl-with-bazel/src/crypto/x509/a_strex.c +3 -3
  164. data/third_party/boringssl-with-bazel/src/crypto/x509/algorithm.c +0 -8
  165. data/third_party/boringssl-with-bazel/src/crypto/x509/t_crl.c +3 -3
  166. data/third_party/boringssl-with-bazel/src/crypto/x509/t_x509.c +1 -1
  167. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +7 -2
  168. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_ext.c +21 -18
  169. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_obj.c +1 -1
  170. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +24 -3
  171. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c +3 -3
  172. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_txt.c +67 -67
  173. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_v3.c +3 -3
  174. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +29 -35
  175. data/third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c +13 -2
  176. data/third_party/boringssl-with-bazel/src/crypto/x509/x509name.c +9 -8
  177. data/third_party/boringssl-with-bazel/src/crypto/x509/x_all.c +10 -10
  178. data/third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c +2 -2
  179. data/third_party/boringssl-with-bazel/src/crypto/x509/x_name.c +28 -40
  180. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c +3 -1
  181. data/third_party/boringssl-with-bazel/src/crypto/x509v3/ext_dat.h +1 -4
  182. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_conf.c +7 -3
  183. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_genn.c +2 -2
  184. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_info.c +1 -1
  185. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +55 -8
  186. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_skey.c +1 -1
  187. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +0 -1
  188. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +1 -1
  189. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +6 -0
  190. data/third_party/boringssl-with-bazel/src/include/openssl/crypto.h +1 -1
  191. data/third_party/boringssl-with-bazel/src/include/openssl/dh.h +12 -0
  192. data/third_party/boringssl-with-bazel/src/include/openssl/digest.h +9 -0
  193. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +4 -1
  194. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +9 -2
  195. data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +26 -6
  196. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +188 -78
  197. data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +52 -43
  198. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +18 -18
  199. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +2 -3
  200. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +1 -1
  201. data/third_party/boringssl-with-bazel/src/ssl/internal.h +9 -9
  202. data/third_party/boringssl-with-bazel/src/ssl/ssl_cipher.cc +8 -9
  203. data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +1 -2
  204. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +4 -8
  205. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +2 -2
  206. metadata +72 -42
  207. data/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc +0 -537
  208. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +0 -1141
  209. data/src/core/ext/upb-generated/gogoproto/gogo.upb.c +0 -17
  210. data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +0 -29
  211. data/src/core/ext/xds/xds_channel.h +0 -46
  212. data/src/core/ext/xds/xds_channel_secure.cc +0 -103
  213. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_pku.c +0 -110
  214. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_sxnet.c +0 -274
@@ -219,11 +219,6 @@ GRPCAPI grpc_call* grpc_channel_create_call(
219
219
  grpc_completion_queue* completion_queue, grpc_slice method,
220
220
  const grpc_slice* host, gpr_timespec deadline, void* reserved);
221
221
 
222
- /** Ping the channels peer (load balanced channels will select one sub-channel
223
- to ping); if the channel is not connected, posts a failed. */
224
- GRPCAPI void grpc_channel_ping(grpc_channel* channel, grpc_completion_queue* cq,
225
- void* tag, void* reserved);
226
-
227
222
  /** Pre-register a method/host pair on a channel.
228
223
  method and host are not owned and must remain alive while the channel is
229
224
  alive. */
@@ -1029,6 +1029,22 @@ grpc_channel_credentials* grpc_tls_credentials_create(
1029
1029
  grpc_server_credentials* grpc_tls_server_credentials_create(
1030
1030
  grpc_tls_credentials_options* options);
1031
1031
 
1032
+ /**
1033
+ * EXPERIMENTAL API - Subject to change
1034
+ *
1035
+ * This method creates an XDS channel credentials object.
1036
+ *
1037
+ * Creating a channel with credentials of this type indicates that an xDS
1038
+ * channel should get credentials configuration from the xDS control plane.
1039
+ *
1040
+ * \a fallback_credentials are used if the channel target does not have the
1041
+ * 'xds:///' scheme or if the xDS control plane does not provide information on
1042
+ * how to fetch credentials dynamically. Does NOT take ownership of the \a
1043
+ * fallback_credentials. (Internally takes a ref to the object.)
1044
+ */
1045
+ GRPCAPI grpc_channel_credentials* grpc_xds_credentials_create(
1046
+ grpc_channel_credentials* fallback_credentials);
1047
+
1032
1048
  #ifdef __cplusplus
1033
1049
  }
1034
1050
  #endif
@@ -355,11 +355,6 @@ typedef struct {
355
355
  over to the next priority. Default value is 10 seconds. */
356
356
  #define GRPC_ARG_PRIORITY_FAILOVER_TIMEOUT_MS \
357
357
  "grpc.priority_failover_timeout_ms"
358
- /* Timeout in milliseconds to wait for a resource to be returned from
359
- * the xds server before assuming that it does not exist.
360
- * The default is 15 seconds. */
361
- #define GRPC_ARG_XDS_RESOURCE_DOES_NOT_EXIST_TIMEOUT_MS \
362
- "grpc.xds_resource_does_not_exist_timeout_ms"
363
358
  /** If non-zero, grpc server's cronet compression workaround will be enabled */
364
359
  #define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \
365
360
  "grpc.workaround.cronet_compression"
@@ -241,17 +241,15 @@ class ChannelData {
241
241
  public:
242
242
  explicit ChannelConfigHelper(ChannelData* chand) : chand_(chand) {}
243
243
 
244
- ApplyServiceConfigResult ApplyServiceConfig(
244
+ ChooseServiceConfigResult ChooseServiceConfig(
245
245
  const Resolver::Result& result) override;
246
246
 
247
- void ApplyConfigSelector(
248
- bool service_config_changed,
249
- RefCountedPtr<ConfigSelector> config_selector) override;
247
+ void StartUsingServiceConfigForCalls() override;
250
248
 
251
249
  void ResolverTransientFailure(grpc_error* error) override;
252
250
 
253
251
  private:
254
- static void ProcessLbPolicy(
252
+ static void ChooseLbPolicy(
255
253
  const Resolver::Result& resolver_result,
256
254
  const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
257
255
  RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
@@ -267,9 +265,13 @@ class ChannelData {
267
265
  const char* reason,
268
266
  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker);
269
267
 
270
- void UpdateServiceConfigInDataPlaneLocked(
271
- bool service_config_changed,
272
- RefCountedPtr<ConfigSelector> config_selector);
268
+ void UpdateServiceConfigInControlPlaneLocked(
269
+ RefCountedPtr<ServiceConfig> service_config,
270
+ RefCountedPtr<ConfigSelector> config_selector,
271
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
272
+ const char* lb_policy_name);
273
+
274
+ void UpdateServiceConfigInDataPlaneLocked();
273
275
 
274
276
  void CreateResolvingLoadBalancingPolicyLocked();
275
277
 
@@ -320,7 +322,6 @@ class ChannelData {
320
322
  grpc_core::UniquePtr<char> health_check_service_name_;
321
323
  RefCountedPtr<ServiceConfig> saved_service_config_;
322
324
  RefCountedPtr<ConfigSelector> saved_config_selector_;
323
- bool received_first_resolver_result_ = false;
324
325
  // The number of SubchannelWrapper instances referencing a given Subchannel.
325
326
  std::map<Subchannel*, int> subchannel_refcount_map_;
326
327
  // The set of SubchannelWrappers that currently exist.
@@ -881,6 +882,9 @@ class CallData {
881
882
  // ChannelData::SubchannelWrapper
882
883
  //
883
884
 
885
+ using ServerAddressAttributeMap =
886
+ std::map<const char*, std::unique_ptr<ServerAddress::AttributeInterface>>;
887
+
884
888
  // This class is a wrapper for Subchannel that hides details of the
885
889
  // channel's implementation (such as the health check service name and
886
890
  // connected subchannel) from the LB policy API.
@@ -892,11 +896,13 @@ class CallData {
892
896
  class ChannelData::SubchannelWrapper : public SubchannelInterface {
893
897
  public:
894
898
  SubchannelWrapper(ChannelData* chand, Subchannel* subchannel,
895
- grpc_core::UniquePtr<char> health_check_service_name)
899
+ grpc_core::UniquePtr<char> health_check_service_name,
900
+ ServerAddressAttributeMap attributes)
896
901
  : SubchannelInterface(&grpc_client_channel_routing_trace),
897
902
  chand_(chand),
898
903
  subchannel_(subchannel),
899
- health_check_service_name_(std::move(health_check_service_name)) {
904
+ health_check_service_name_(std::move(health_check_service_name)),
905
+ attributes_(std::move(attributes)) {
900
906
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
901
907
  gpr_log(GPR_INFO,
902
908
  "chand=%p: creating subchannel wrapper %p for subchannel %p",
@@ -974,14 +980,21 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
974
980
 
975
981
  void ResetBackoff() override { subchannel_->ResetBackoff(); }
976
982
 
977
- void ThrottleKeepaliveTime(int new_keepalive_time) {
978
- subchannel_->ThrottleKeepaliveTime(new_keepalive_time);
979
- }
980
-
981
983
  const grpc_channel_args* channel_args() override {
982
984
  return subchannel_->channel_args();
983
985
  }
984
986
 
987
+ const ServerAddress::AttributeInterface* GetAttribute(
988
+ const char* key) const override {
989
+ auto it = attributes_.find(key);
990
+ if (it == attributes_.end()) return nullptr;
991
+ return it->second.get();
992
+ }
993
+
994
+ void ThrottleKeepaliveTime(int new_keepalive_time) {
995
+ subchannel_->ThrottleKeepaliveTime(new_keepalive_time);
996
+ }
997
+
985
998
  void UpdateHealthCheckServiceName(
986
999
  grpc_core::UniquePtr<char> health_check_service_name) {
987
1000
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
@@ -1175,6 +1188,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
1175
1188
  ChannelData* chand_;
1176
1189
  Subchannel* subchannel_;
1177
1190
  grpc_core::UniquePtr<char> health_check_service_name_;
1191
+ ServerAddressAttributeMap attributes_;
1178
1192
  // Maps from the address of the watcher passed to us by the LB policy
1179
1193
  // to the address of the WrapperWatcher that we passed to the underlying
1180
1194
  // subchannel. This is needed so that when the LB policy calls
@@ -1349,6 +1363,18 @@ class ChannelData::ConnectivityWatcherRemover {
1349
1363
  // ChannelData::ClientChannelControlHelper
1350
1364
  //
1351
1365
 
1366
+ } // namespace
1367
+
1368
+ // Allows accessing the attributes from a ServerAddress.
1369
+ class ChannelServerAddressPeer {
1370
+ public:
1371
+ static ServerAddressAttributeMap GetAttributes(ServerAddress* address) {
1372
+ return std::move(address->attributes_);
1373
+ }
1374
+ };
1375
+
1376
+ namespace {
1377
+
1352
1378
  class ChannelData::ClientChannelControlHelper
1353
1379
  : public LoadBalancingPolicy::ChannelControlHelper {
1354
1380
  public:
@@ -1362,7 +1388,8 @@ class ChannelData::ClientChannelControlHelper
1362
1388
  }
1363
1389
 
1364
1390
  RefCountedPtr<SubchannelInterface> CreateSubchannel(
1365
- const grpc_channel_args& args) override {
1391
+ ServerAddress address, const grpc_channel_args& args) override {
1392
+ // Determine health check service name.
1366
1393
  bool inhibit_health_checking = grpc_channel_arg_get_bool(
1367
1394
  grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false);
1368
1395
  grpc_core::UniquePtr<char> health_check_service_name;
@@ -1370,21 +1397,37 @@ class ChannelData::ClientChannelControlHelper
1370
1397
  health_check_service_name.reset(
1371
1398
  gpr_strdup(chand_->health_check_service_name_.get()));
1372
1399
  }
1400
+ // Remove channel args that should not affect subchannel uniqueness.
1373
1401
  static const char* args_to_remove[] = {
1374
1402
  GRPC_ARG_INHIBIT_HEALTH_CHECKING,
1375
1403
  GRPC_ARG_CHANNELZ_CHANNEL_NODE,
1376
1404
  };
1377
- grpc_arg arg = SubchannelPoolInterface::CreateChannelArg(
1378
- chand_->subchannel_pool_.get());
1405
+ // Add channel args needed for the subchannel.
1406
+ absl::InlinedVector<grpc_arg, 3> args_to_add = {
1407
+ Subchannel::CreateSubchannelAddressArg(&address.address()),
1408
+ SubchannelPoolInterface::CreateChannelArg(
1409
+ chand_->subchannel_pool_.get()),
1410
+ };
1411
+ if (address.args() != nullptr) {
1412
+ for (size_t j = 0; j < address.args()->num_args; ++j) {
1413
+ args_to_add.emplace_back(address.args()->args[j]);
1414
+ }
1415
+ }
1379
1416
  grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
1380
- &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &arg, 1);
1417
+ &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove),
1418
+ args_to_add.data(), args_to_add.size());
1419
+ gpr_free(args_to_add[0].value.string);
1420
+ // Create subchannel.
1381
1421
  Subchannel* subchannel =
1382
1422
  chand_->client_channel_factory_->CreateSubchannel(new_args);
1383
1423
  grpc_channel_args_destroy(new_args);
1384
1424
  if (subchannel == nullptr) return nullptr;
1425
+ // Make sure the subchannel has updated keepalive time.
1385
1426
  subchannel->ThrottleKeepaliveTime(chand_->keepalive_time_);
1427
+ // Create and return wrapper for the subchannel.
1386
1428
  return MakeRefCounted<SubchannelWrapper>(
1387
- chand_, subchannel, std::move(health_check_service_name));
1429
+ chand_, subchannel, std::move(health_check_service_name),
1430
+ ChannelServerAddressPeer::GetAttributes(&address));
1388
1431
  }
1389
1432
 
1390
1433
  void UpdateState(
@@ -1433,19 +1476,19 @@ class ChannelData::ClientChannelControlHelper
1433
1476
  // ChannelData::ChannelConfigHelper
1434
1477
  //
1435
1478
 
1436
- // Synchronous callback from ResolvingLoadBalancingPolicy to process a
1437
- // resolver result update.
1438
- ChannelData::ChannelConfigHelper::ApplyServiceConfigResult
1439
- ChannelData::ChannelConfigHelper::ApplyServiceConfig(
1479
+ ChannelData::ChannelConfigHelper::ChooseServiceConfigResult
1480
+ ChannelData::ChannelConfigHelper::ChooseServiceConfig(
1440
1481
  const Resolver::Result& result) {
1441
- ApplyServiceConfigResult service_config_result;
1482
+ ChooseServiceConfigResult service_config_result;
1442
1483
  RefCountedPtr<ServiceConfig> service_config;
1443
- // If resolver did not return a service config or returned an invalid service
1444
- // config, we need a fallback service config.
1484
+ RefCountedPtr<ConfigSelector> config_selector;
1445
1485
  if (result.service_config_error != GRPC_ERROR_NONE) {
1446
- // If the service config was invalid, then fallback to the saved service
1447
- // config. If there is no saved config either, use the default service
1448
- // config.
1486
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1487
+ gpr_log(GPR_INFO, "chand=%p: resolver returned service config error: %s",
1488
+ chand_, grpc_error_string(result.service_config_error));
1489
+ }
1490
+ // If the service config was invalid, then fallback to the
1491
+ // previously returned service config.
1449
1492
  if (chand_->saved_service_config_ != nullptr) {
1450
1493
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1451
1494
  gpr_log(GPR_INFO,
@@ -1454,99 +1497,60 @@ ChannelData::ChannelConfigHelper::ApplyServiceConfig(
1454
1497
  chand_);
1455
1498
  }
1456
1499
  service_config = chand_->saved_service_config_;
1457
- } else if (chand_->default_service_config_ != nullptr) {
1458
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1459
- gpr_log(GPR_INFO,
1460
- "chand=%p: resolver returned invalid service config. Using "
1461
- "default service config provided by client API.",
1462
- chand_);
1463
- }
1464
- service_config = chand_->default_service_config_;
1500
+ config_selector = chand_->saved_config_selector_;
1501
+ } else {
1502
+ // No previously returned config, so put the channel into
1503
+ // TRANSIENT_FAILURE.
1504
+ service_config_result.no_valid_service_config = true;
1505
+ return service_config_result;
1465
1506
  }
1466
1507
  } else if (result.service_config == nullptr) {
1467
- if (chand_->default_service_config_ != nullptr) {
1468
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1469
- gpr_log(GPR_INFO,
1470
- "chand=%p: resolver returned no service config. Using default "
1471
- "service config provided by client API.",
1472
- chand_);
1473
- }
1474
- service_config = chand_->default_service_config_;
1508
+ // Resolver did not return any service config.
1509
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1510
+ gpr_log(GPR_INFO,
1511
+ "chand=%p: resolver returned no service config. Using default "
1512
+ "service config for channel.",
1513
+ chand_);
1475
1514
  }
1515
+ service_config = chand_->default_service_config_;
1476
1516
  } else {
1517
+ // Use ServiceConfig and ConfigSelector returned by resolver.
1477
1518
  service_config = result.service_config;
1519
+ config_selector = ConfigSelector::GetFromChannelArgs(*result.args);
1478
1520
  }
1479
- service_config_result.service_config_error =
1480
- GRPC_ERROR_REF(result.service_config_error);
1481
- if (service_config == nullptr &&
1482
- result.service_config_error != GRPC_ERROR_NONE) {
1483
- service_config_result.no_valid_service_config = true;
1484
- return service_config_result;
1485
- }
1486
- // Process service config.
1487
- grpc_core::UniquePtr<char> service_config_json;
1521
+ GPR_ASSERT(service_config != nullptr);
1522
+ // Extract global config for client channel.
1488
1523
  const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1489
- nullptr;
1490
- if (service_config != nullptr) {
1491
- parsed_service_config =
1492
- static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1493
- service_config->GetGlobalParsedConfig(
1494
- internal::ClientChannelServiceConfigParser::ParserIndex()));
1495
- }
1496
- // Check if the config has changed.
1524
+ static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1525
+ service_config->GetGlobalParsedConfig(
1526
+ internal::ClientChannelServiceConfigParser::ParserIndex()));
1527
+ // Find LB policy config.
1528
+ ChooseLbPolicy(result, parsed_service_config,
1529
+ &service_config_result.lb_policy_config);
1530
+ // Check if the ServiceConfig has changed.
1531
+ const bool service_config_changed =
1532
+ chand_->saved_service_config_ == nullptr ||
1533
+ service_config->json_string() !=
1534
+ chand_->saved_service_config_->json_string();
1535
+ // Check if the ConfigSelector has changed.
1536
+ const bool config_selector_changed = !ConfigSelector::Equals(
1537
+ chand_->saved_config_selector_.get(), config_selector.get());
1538
+ // Indicate a change if either the ServiceConfig or ConfigSelector have
1539
+ // changed.
1497
1540
  service_config_result.service_config_changed =
1498
- ((service_config == nullptr) !=
1499
- (chand_->saved_service_config_ == nullptr)) ||
1500
- (service_config != nullptr &&
1501
- service_config->json_string() !=
1502
- chand_->saved_service_config_->json_string());
1541
+ service_config_changed || config_selector_changed;
1542
+ // If it has, apply the global parameters now.
1503
1543
  if (service_config_result.service_config_changed) {
1504
- service_config_json.reset(gpr_strdup(
1505
- service_config != nullptr ? service_config->json_string().c_str()
1506
- : ""));
1507
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1508
- gpr_log(GPR_INFO,
1509
- "chand=%p: resolver returned updated service config: \"%s\"",
1510
- chand_, service_config_json.get());
1511
- }
1512
- // Save health check service name.
1513
- if (service_config != nullptr) {
1514
- chand_->health_check_service_name_.reset(
1515
- gpr_strdup(parsed_service_config->health_check_service_name()));
1516
- } else {
1517
- chand_->health_check_service_name_.reset();
1518
- }
1519
- // Update health check service name used by existing subchannel wrappers.
1520
- for (auto* subchannel_wrapper : chand_->subchannel_wrappers_) {
1521
- subchannel_wrapper->UpdateHealthCheckServiceName(
1522
- grpc_core::UniquePtr<char>(
1523
- gpr_strdup(chand_->health_check_service_name_.get())));
1524
- }
1525
- // Save service config.
1526
- chand_->saved_service_config_ = std::move(service_config);
1527
- }
1528
- // Find LB policy config.
1529
- ProcessLbPolicy(result, parsed_service_config,
1530
- &service_config_result.lb_policy_config);
1531
- grpc_core::UniquePtr<char> lb_policy_name(
1532
- gpr_strdup((service_config_result.lb_policy_config)->name()));
1533
- // Swap out the data used by GetChannelInfo().
1534
- {
1535
- MutexLock lock(&chand_->info_mu_);
1536
- chand_->info_lb_policy_name_ = std::move(lb_policy_name);
1537
- if (service_config_json != nullptr) {
1538
- chand_->info_service_config_json_ = std::move(service_config_json);
1539
- }
1544
+ chand_->UpdateServiceConfigInControlPlaneLocked(
1545
+ std::move(service_config), std::move(config_selector),
1546
+ parsed_service_config, service_config_result.lb_policy_config->name());
1540
1547
  }
1541
1548
  // Return results.
1542
1549
  return service_config_result;
1543
1550
  }
1544
1551
 
1545
- void ChannelData::ChannelConfigHelper::ApplyConfigSelector(
1546
- bool service_config_changed,
1547
- RefCountedPtr<ConfigSelector> config_selector) {
1548
- chand_->UpdateServiceConfigInDataPlaneLocked(service_config_changed,
1549
- std::move(config_selector));
1552
+ void ChannelData::ChannelConfigHelper::StartUsingServiceConfigForCalls() {
1553
+ chand_->UpdateServiceConfigInDataPlaneLocked();
1550
1554
  }
1551
1555
 
1552
1556
  void ChannelData::ChannelConfigHelper::ResolverTransientFailure(
@@ -1556,21 +1560,19 @@ void ChannelData::ChannelConfigHelper::ResolverTransientFailure(
1556
1560
  chand_->resolver_transient_failure_error_ = error;
1557
1561
  }
1558
1562
 
1559
- void ChannelData::ChannelConfigHelper::ProcessLbPolicy(
1563
+ void ChannelData::ChannelConfigHelper::ChooseLbPolicy(
1560
1564
  const Resolver::Result& resolver_result,
1561
1565
  const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
1562
1566
  RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
1563
1567
  // Prefer the LB policy config found in the service config.
1564
- if (parsed_service_config != nullptr &&
1565
- parsed_service_config->parsed_lb_config() != nullptr) {
1568
+ if (parsed_service_config->parsed_lb_config() != nullptr) {
1566
1569
  *lb_policy_config = parsed_service_config->parsed_lb_config();
1567
1570
  return;
1568
1571
  }
1569
1572
  // Try the deprecated LB policy name from the service config.
1570
1573
  // If not, try the setting from channel args.
1571
1574
  const char* policy_name = nullptr;
1572
- if (parsed_service_config != nullptr &&
1573
- !parsed_service_config->parsed_deprecated_lb_policy().empty()) {
1575
+ if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
1574
1576
  policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
1575
1577
  } else {
1576
1578
  const grpc_arg* channel_arg =
@@ -1690,16 +1692,17 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
1690
1692
  "filter");
1691
1693
  return;
1692
1694
  }
1693
- // Get default service config
1695
+ // Get default service config. If none is specified via the client API,
1696
+ // we use an empty config.
1694
1697
  const char* service_config_json = grpc_channel_arg_get_string(
1695
1698
  grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG));
1696
- if (service_config_json != nullptr) {
1697
- *error = GRPC_ERROR_NONE;
1698
- default_service_config_ = ServiceConfig::Create(service_config_json, error);
1699
- if (*error != GRPC_ERROR_NONE) {
1700
- default_service_config_.reset();
1701
- return;
1702
- }
1699
+ if (service_config_json == nullptr) service_config_json = "{}";
1700
+ *error = GRPC_ERROR_NONE;
1701
+ default_service_config_ =
1702
+ ServiceConfig::Create(args->channel_args, service_config_json, error);
1703
+ if (*error != GRPC_ERROR_NONE) {
1704
+ default_service_config_.reset();
1705
+ return;
1703
1706
  }
1704
1707
  grpc_uri* uri = grpc_uri_parse(server_uri, true);
1705
1708
  if (uri != nullptr && uri->path[0] != '\0') {
@@ -1713,9 +1716,12 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
1713
1716
  &new_args);
1714
1717
  target_uri_.reset(proxy_name != nullptr ? proxy_name
1715
1718
  : gpr_strdup(server_uri));
1716
- channel_args_ = new_args != nullptr
1717
- ? new_args
1718
- : grpc_channel_args_copy(args->channel_args);
1719
+ // Strip out service config channel arg, so that it doesn't affect
1720
+ // subchannel uniqueness when the args flow down to that layer.
1721
+ const char* arg_to_remove = GRPC_ARG_SERVICE_CONFIG;
1722
+ channel_args_ = grpc_channel_args_copy_and_remove(
1723
+ new_args != nullptr ? new_args : args->channel_args, &arg_to_remove, 1);
1724
+ grpc_channel_args_destroy(new_args);
1719
1725
  keepalive_time_ = grpc_channel_args_find_integer(
1720
1726
  channel_args_, GRPC_ARG_KEEPALIVE_TIME_MS,
1721
1727
  {-1 /* default value, unset */, 1, INT_MAX});
@@ -1747,11 +1753,10 @@ void ChannelData::UpdateStateAndPickerLocked(
1747
1753
  const char* reason,
1748
1754
  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) {
1749
1755
  // Clean the control plane when entering IDLE.
1750
- if (picker_ == nullptr) {
1756
+ if (picker == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
1751
1757
  health_check_service_name_.reset();
1752
1758
  saved_service_config_.reset();
1753
1759
  saved_config_selector_.reset();
1754
- received_first_resolver_result_ = false;
1755
1760
  }
1756
1761
  // Update connectivity state.
1757
1762
  state_tracker_.SetState(state, status, reason);
@@ -1797,7 +1802,7 @@ void ChannelData::UpdateStateAndPickerLocked(
1797
1802
  // Note: Original value will be destroyed after the lock is released.
1798
1803
  picker_.swap(picker);
1799
1804
  // Clean the data plane if the updated picker is nullptr.
1800
- if (picker_ == nullptr) {
1805
+ if (picker_ == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
1801
1806
  received_service_config_data_ = false;
1802
1807
  // Note: We save the objects to unref until after the lock is released.
1803
1808
  retry_throttle_data_to_unref = std::move(retry_throttle_data_);
@@ -1819,43 +1824,72 @@ void ChannelData::UpdateStateAndPickerLocked(
1819
1824
  pending_subchannel_updates_.clear();
1820
1825
  }
1821
1826
 
1822
- void ChannelData::UpdateServiceConfigInDataPlaneLocked(
1823
- bool service_config_changed,
1824
- RefCountedPtr<ConfigSelector> config_selector) {
1825
- // Check if ConfigSelector has changed.
1826
- const bool config_selector_changed =
1827
- saved_config_selector_ != config_selector;
1828
- saved_config_selector_ = config_selector;
1829
- // We want to set the service config at least once, even if the
1830
- // resolver does not return a config, because that ensures that we
1831
- // disable retries if they are not enabled in the service config.
1832
- // TODO(roth): Consider removing the received_first_resolver_result_ check
1833
- // when we implement transparent retries.
1834
- if (!service_config_changed && !config_selector_changed &&
1835
- received_first_resolver_result_) {
1836
- return;
1827
+ void ChannelData::UpdateServiceConfigInControlPlaneLocked(
1828
+ RefCountedPtr<ServiceConfig> service_config,
1829
+ RefCountedPtr<ConfigSelector> config_selector,
1830
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
1831
+ const char* lb_policy_name) {
1832
+ grpc_core::UniquePtr<char> service_config_json(
1833
+ gpr_strdup(service_config->json_string().c_str()));
1834
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1835
+ gpr_log(GPR_INFO,
1836
+ "chand=%p: resolver returned updated service config: \"%s\"", this,
1837
+ service_config_json.get());
1838
+ }
1839
+ // Save service config.
1840
+ saved_service_config_ = std::move(service_config);
1841
+ // Update health check service name if needed.
1842
+ if (((health_check_service_name_ == nullptr) !=
1843
+ (parsed_service_config->health_check_service_name() == nullptr)) ||
1844
+ (health_check_service_name_ != nullptr &&
1845
+ strcmp(health_check_service_name_.get(),
1846
+ parsed_service_config->health_check_service_name()) != 0)) {
1847
+ health_check_service_name_.reset(
1848
+ gpr_strdup(parsed_service_config->health_check_service_name()));
1849
+ // Update health check service name used by existing subchannel wrappers.
1850
+ for (auto* subchannel_wrapper : subchannel_wrappers_) {
1851
+ subchannel_wrapper->UpdateHealthCheckServiceName(
1852
+ grpc_core::UniquePtr<char>(
1853
+ gpr_strdup(health_check_service_name_.get())));
1854
+ }
1837
1855
  }
1838
- received_first_resolver_result_ = true;
1856
+ // Swap out the data used by GetChannelInfo().
1857
+ grpc_core::UniquePtr<char> lb_policy_name_owned(gpr_strdup(lb_policy_name));
1858
+ {
1859
+ MutexLock lock(&info_mu_);
1860
+ info_lb_policy_name_ = std::move(lb_policy_name_owned);
1861
+ info_service_config_json_ = std::move(service_config_json);
1862
+ }
1863
+ // Save config selector.
1864
+ saved_config_selector_ = std::move(config_selector);
1865
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1866
+ gpr_log(GPR_INFO, "chand=%p: using ConfigSelector %p", this,
1867
+ saved_config_selector_.get());
1868
+ }
1869
+ }
1870
+
1871
+ void ChannelData::UpdateServiceConfigInDataPlaneLocked() {
1839
1872
  // Get retry throttle data from service config.
1873
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1874
+ static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1875
+ saved_service_config_->GetGlobalParsedConfig(
1876
+ internal::ClientChannelServiceConfigParser::ParserIndex()));
1877
+ absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
1878
+ retry_throttle_config = parsed_service_config->retry_throttling();
1840
1879
  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
1841
- if (saved_service_config_ != nullptr) {
1842
- const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1843
- static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1844
- saved_service_config_->GetGlobalParsedConfig(
1845
- internal::ClientChannelServiceConfigParser::ParserIndex()));
1846
- if (parsed_service_config != nullptr) {
1847
- absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
1848
- retry_throttle_config = parsed_service_config->retry_throttling();
1849
- if (retry_throttle_config.has_value()) {
1850
- retry_throttle_data =
1851
- internal::ServerRetryThrottleMap::GetDataForServer(
1852
- server_name_.get(),
1853
- retry_throttle_config.value().max_milli_tokens,
1854
- retry_throttle_config.value().milli_token_ratio);
1855
- }
1856
- }
1880
+ if (retry_throttle_config.has_value()) {
1881
+ retry_throttle_data = internal::ServerRetryThrottleMap::GetDataForServer(
1882
+ server_name_.get(), retry_throttle_config.value().max_milli_tokens,
1883
+ retry_throttle_config.value().milli_token_ratio);
1884
+ }
1885
+ // Grab ref to service config.
1886
+ RefCountedPtr<ServiceConfig> service_config = saved_service_config_;
1887
+ // Grab ref to config selector. Use default if resolver didn't supply one.
1888
+ RefCountedPtr<ConfigSelector> config_selector = saved_config_selector_;
1889
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1890
+ gpr_log(GPR_INFO, "chand=%p: switching to ConfigSelector %p", this,
1891
+ saved_config_selector_.get());
1857
1892
  }
1858
- // Create default config selector if not provided by resolver.
1859
1893
  if (config_selector == nullptr) {
1860
1894
  config_selector =
1861
1895
  MakeRefCounted<DefaultConfigSelector>(saved_service_config_);
@@ -1864,9 +1898,6 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked(
1864
1898
  //
1865
1899
  // We defer unreffing the old values (and deallocating memory) until
1866
1900
  // after releasing the lock to keep the critical section small.
1867
- RefCountedPtr<ServiceConfig> service_config_to_unref = saved_service_config_;
1868
- RefCountedPtr<ConfigSelector> config_selector_to_unref =
1869
- std::move(config_selector);
1870
1901
  {
1871
1902
  MutexLock lock(&data_plane_mu_);
1872
1903
  GRPC_ERROR_UNREF(resolver_transient_failure_error_);
@@ -1875,8 +1906,8 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked(
1875
1906
  received_service_config_data_ = true;
1876
1907
  // Old values will be unreffed after lock is released.
1877
1908
  retry_throttle_data_.swap(retry_throttle_data);
1878
- service_config_.swap(service_config_to_unref);
1879
- config_selector_.swap(config_selector_to_unref);
1909
+ service_config_.swap(service_config);
1910
+ config_selector_.swap(config_selector);
1880
1911
  // Re-process queued picks.
1881
1912
  for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
1882
1913
  grpc_call_element* elem = pick->elem;
@@ -3873,6 +3904,7 @@ class CallData::QueuedPickCanceller {
3873
3904
  }
3874
3905
  if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) {
3875
3906
  // Remove pick from list of queued picks.
3907
+ calld->MaybeInvokeConfigSelectorCommitCallback();
3876
3908
  calld->MaybeRemoveCallFromQueuedPicksLocked(self->elem_);
3877
3909
  // Fail pending batches on the call.
3878
3910
  calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error),
@@ -3921,8 +3953,7 @@ grpc_error* CallData::ApplyServiceConfigToCallLocked(
3921
3953
  chand, this);
3922
3954
  }
3923
3955
  ConfigSelector* config_selector = chand->config_selector();
3924
- auto service_config = chand->service_config();
3925
- if (service_config != nullptr) {
3956
+ if (config_selector != nullptr) {
3926
3957
  // Use the ConfigSelector to determine the config for the call.
3927
3958
  ConfigSelector::CallConfig call_config =
3928
3959
  config_selector->GetCallConfig({&path_, initial_metadata, arena_});
@@ -3935,7 +3966,8 @@ grpc_error* CallData::ApplyServiceConfigToCallLocked(
3935
3966
  // so that it can be accessed by filters in the subchannel, and it
3936
3967
  // will be cleaned up when the call ends.
3937
3968
  auto* service_config_call_data = arena_->New<ServiceConfigCallData>(
3938
- std::move(service_config), call_config.method_configs, call_context_);
3969
+ std::move(call_config.service_config), call_config.method_configs,
3970
+ call_context_);
3939
3971
  // Apply our own method params to the call.
3940
3972
  method_params_ = static_cast<ClientChannelMethodParsedConfig*>(
3941
3973
  service_config_call_data->GetMethodParsedConfig(
@@ -4162,7 +4194,9 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
4162
4194
  connected_subchannel_ =
4163
4195
  chand->GetConnectedSubchannelInDataPlane(result.subchannel.get());
4164
4196
  GPR_ASSERT(connected_subchannel_ != nullptr);
4165
- if (retry_committed_) MaybeInvokeConfigSelectorCommitCallback();
4197
+ if (!enable_retries_ || retry_committed_) {
4198
+ MaybeInvokeConfigSelectorCommitCallback();
4199
+ }
4166
4200
  }
4167
4201
  lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready;
4168
4202
  *error = result.error;