grpc 1.30.0 → 1.31.1

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 (383) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +560 -619
  3. data/include/grpc/grpc_security.h +8 -0
  4. data/include/grpc/grpc_security_constants.h +3 -0
  5. data/include/grpc/impl/codegen/grpc_types.h +7 -5
  6. data/include/grpc/impl/codegen/port_platform.h +0 -32
  7. data/src/core/ext/filters/client_channel/backend_metric.cc +12 -9
  8. data/src/core/ext/filters/client_channel/client_channel.cc +406 -261
  9. data/src/core/ext/filters/client_channel/config_selector.cc +62 -0
  10. data/src/core/ext/filters/client_channel/config_selector.h +93 -0
  11. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +24 -2
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +2 -0
  13. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +6 -5
  14. data/src/core/ext/filters/client_channel/http_proxy.cc +6 -4
  15. data/src/core/ext/filters/client_channel/lb_policy.h +2 -0
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +39 -23
  17. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +4 -6
  18. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -4
  19. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +381 -72
  20. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +4 -5
  21. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -2
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +6 -5
  23. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +8 -6
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +9 -7
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +7 -5
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +33 -48
  27. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +6 -2
  28. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +21 -18
  29. data/src/core/ext/filters/client_channel/resolver_registry.cc +13 -14
  30. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +6 -7
  31. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +33 -28
  32. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +39 -20
  33. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +142 -0
  34. data/src/core/ext/filters/client_channel/subchannel.cc +1 -1
  35. data/src/core/ext/filters/client_channel/xds/xds_api.cc +327 -123
  36. data/src/core/ext/filters/client_channel/xds/xds_api.h +72 -7
  37. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +12 -23
  38. data/src/core/ext/filters/client_channel/xds/xds_client.cc +112 -33
  39. data/src/core/ext/filters/client_channel/xds/xds_client_stats.h +10 -10
  40. data/src/core/ext/filters/http/client/http_client_filter.cc +5 -5
  41. data/src/core/ext/filters/http/http_filters_plugin.cc +2 -1
  42. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +74 -33
  43. data/src/core/ext/filters/http/message_compress/message_decompress_filter.h +3 -1
  44. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -80
  45. data/src/core/ext/filters/message_size/message_size_filter.h +6 -0
  46. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +383 -347
  47. data/src/core/ext/transport/chttp2/server/chttp2_server.h +6 -2
  48. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +1 -1
  49. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +7 -13
  50. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +7 -8
  51. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +19 -4
  52. data/src/core/ext/transport/chttp2/transport/flow_control.cc +22 -27
  53. data/src/core/ext/transport/chttp2/transport/flow_control.h +14 -16
  54. data/src/core/ext/transport/chttp2/transport/frame_data.cc +9 -12
  55. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +4 -6
  56. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -6
  57. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +12 -13
  58. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +6 -7
  59. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +9 -12
  60. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +25 -29
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +13 -17
  62. data/src/core/ext/transport/chttp2/transport/internal.h +13 -0
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +33 -43
  64. data/src/core/ext/transport/chttp2/transport/writing.cc +9 -14
  65. data/src/core/ext/transport/inproc/inproc_transport.cc +35 -15
  66. data/src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h +0 -1
  67. data/src/core/ext/upb-generated/envoy/annotations/resource.upb.h +3 -4
  68. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h +0 -1
  69. data/src/core/ext/upb-generated/envoy/api/v2/auth/common.upb.h +80 -69
  70. data/src/core/ext/upb-generated/envoy/api/v2/auth/secret.upb.h +24 -23
  71. data/src/core/ext/upb-generated/envoy/api/v2/auth/tls.upb.h +66 -56
  72. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h +1 -2
  73. data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.c +2 -2
  74. data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.h +317 -311
  75. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h +42 -34
  76. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.h +7 -7
  77. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h +79 -61
  78. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +55 -49
  79. data/src/core/ext/upb-generated/envoy/api/v2/core/backoff.upb.h +9 -8
  80. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c +1 -1
  81. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +163 -169
  82. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h +51 -45
  83. data/src/core/ext/upb-generated/envoy/api/v2/core/event_service_config.upb.h +4 -5
  84. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h +107 -100
  85. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +137 -117
  86. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.h +9 -9
  87. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h +105 -87
  88. data/src/core/ext/upb-generated/envoy/api/v2/core/socket_option.upb.h +12 -13
  89. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c +1 -1
  90. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +95 -101
  91. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h +1 -2
  92. data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.c +1 -1
  93. data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.h +49 -65
  94. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h +0 -1
  95. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint_components.upb.h +49 -42
  96. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h +70 -62
  97. data/src/core/ext/upb-generated/envoy/api/v2/lds.upb.h +1 -2
  98. data/src/core/ext/upb-generated/envoy/api/v2/listener.upb.h +81 -65
  99. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener.upb.h +0 -1
  100. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.c +1 -1
  101. data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.h +91 -80
  102. data/src/core/ext/upb-generated/envoy/api/v2/listener/udp_listener_config.upb.h +9 -10
  103. data/src/core/ext/upb-generated/envoy/api/v2/rds.upb.h +1 -2
  104. data/src/core/ext/upb-generated/envoy/api/v2/route.upb.h +36 -31
  105. data/src/core/ext/upb-generated/envoy/api/v2/route/route.upb.h +0 -1
  106. data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.c +7 -7
  107. data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.h +648 -696
  108. data/src/core/ext/upb-generated/envoy/api/v2/scoped_route.upb.h +16 -15
  109. data/src/core/ext/upb-generated/envoy/api/v2/srds.upb.h +1 -2
  110. data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.c +1 -1
  111. data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.h +95 -88
  112. data/src/core/ext/upb-generated/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.upb.h +234 -199
  113. data/src/core/ext/upb-generated/envoy/config/listener/v2/api_listener.upb.h +5 -5
  114. data/src/core/ext/upb-generated/envoy/config/trace/v2/http_tracer.upb.h +13 -13
  115. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h +1 -2
  116. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h +20 -18
  117. data/src/core/ext/upb-generated/envoy/type/http.upb.h +0 -1
  118. data/src/core/ext/upb-generated/envoy/type/matcher/regex.upb.h +18 -17
  119. data/src/core/ext/upb-generated/envoy/type/matcher/string.upb.h +14 -14
  120. data/src/core/ext/upb-generated/envoy/type/metadata/v2/metadata.upb.h +23 -23
  121. data/src/core/ext/upb-generated/envoy/type/percent.upb.h +8 -9
  122. data/src/core/ext/upb-generated/envoy/type/range.upb.h +15 -16
  123. data/src/core/ext/upb-generated/envoy/type/semantic_version.upb.h +7 -8
  124. data/src/core/ext/upb-generated/envoy/type/tracing/v2/custom_tag.upb.h +36 -35
  125. data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +0 -1
  126. data/src/core/ext/upb-generated/google/api/annotations.upb.h +0 -1
  127. data/src/core/ext/upb-generated/google/api/http.upb.h +29 -28
  128. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +5 -6
  129. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +3 -3
  130. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +412 -386
  131. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +5 -6
  132. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +1 -2
  133. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +1 -1
  134. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +33 -54
  135. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +5 -6
  136. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +27 -28
  137. data/src/core/ext/upb-generated/google/rpc/status.upb.h +8 -8
  138. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +1 -1
  139. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +32 -45
  140. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +4 -4
  141. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +157 -178
  142. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +14 -13
  143. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +6 -7
  144. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +59 -56
  145. data/src/core/ext/upb-generated/udpa/annotations/migrate.upb.h +11 -12
  146. data/src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h +0 -1
  147. data/src/core/ext/upb-generated/udpa/annotations/status.upb.h +5 -6
  148. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c +6 -6
  149. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h +41 -68
  150. data/src/core/ext/upb-generated/validate/validate.upb.h +536 -535
  151. data/src/core/lib/channel/channel_trace.cc +2 -6
  152. data/src/core/lib/channel/channelz.cc +5 -15
  153. data/src/core/lib/gpr/log_linux.cc +6 -8
  154. data/src/core/lib/gpr/log_posix.cc +6 -8
  155. data/src/core/lib/gpr/string.cc +10 -9
  156. data/src/core/lib/gpr/string.h +4 -2
  157. data/src/core/lib/gprpp/global_config_env.cc +8 -6
  158. data/src/core/lib/http/httpcli.cc +13 -10
  159. data/src/core/lib/http/httpcli_security_connector.cc +5 -5
  160. data/src/core/lib/iomgr/cfstream_handle.cc +1 -0
  161. data/src/core/lib/iomgr/endpoint_pair_posix.cc +10 -10
  162. data/src/core/lib/iomgr/error_cfstream.cc +9 -8
  163. data/src/core/lib/iomgr/ev_epoll1_linux.cc +5 -6
  164. data/src/core/lib/iomgr/ev_epollex_linux.cc +15 -21
  165. data/src/core/lib/iomgr/ev_poll_posix.cc +6 -5
  166. data/src/core/lib/iomgr/ev_posix.cc +2 -0
  167. data/src/core/lib/iomgr/iomgr.cc +10 -0
  168. data/src/core/lib/iomgr/iomgr.h +10 -0
  169. data/src/core/lib/iomgr/is_epollexclusive_available.cc +14 -0
  170. data/src/core/lib/iomgr/port.h +1 -21
  171. data/src/core/lib/iomgr/resolve_address_custom.cc +13 -18
  172. data/src/core/lib/iomgr/resolve_address_windows.cc +8 -8
  173. data/src/core/lib/iomgr/resource_quota.cc +34 -31
  174. data/src/core/lib/iomgr/sockaddr_utils.cc +7 -5
  175. data/src/core/lib/iomgr/sockaddr_utils.h +1 -1
  176. data/src/core/lib/iomgr/socket_utils_common_posix.cc +95 -55
  177. data/src/core/lib/iomgr/socket_windows.cc +4 -5
  178. data/src/core/lib/iomgr/tcp_client_cfstream.cc +9 -11
  179. data/src/core/lib/iomgr/tcp_client_custom.cc +6 -9
  180. data/src/core/lib/iomgr/tcp_client_posix.cc +27 -36
  181. data/src/core/lib/iomgr/tcp_client_windows.cc +9 -9
  182. data/src/core/lib/iomgr/tcp_custom.cc +1 -1
  183. data/src/core/lib/iomgr/tcp_custom.h +1 -1
  184. data/src/core/lib/iomgr/tcp_server.cc +3 -4
  185. data/src/core/lib/iomgr/tcp_server.h +7 -5
  186. data/src/core/lib/iomgr/tcp_server_custom.cc +6 -14
  187. data/src/core/lib/iomgr/tcp_server_posix.cc +34 -41
  188. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -4
  189. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +5 -7
  190. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +4 -9
  191. data/src/core/lib/iomgr/tcp_server_windows.cc +16 -16
  192. data/src/core/lib/iomgr/timer_generic.cc +13 -12
  193. data/src/core/lib/iomgr/udp_server.cc +24 -23
  194. data/src/core/lib/iomgr/udp_server.h +5 -2
  195. data/src/core/lib/iomgr/unix_sockets_posix.cc +9 -14
  196. data/src/core/lib/iomgr/unix_sockets_posix.h +3 -1
  197. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +5 -2
  198. data/src/core/lib/json/json_reader.cc +20 -21
  199. data/src/core/lib/security/credentials/credentials.h +5 -3
  200. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +8 -6
  201. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +12 -9
  202. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +7 -4
  203. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +19 -28
  204. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -6
  205. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -0
  206. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +10 -0
  207. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +10 -0
  208. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +10 -10
  209. data/src/core/lib/security/security_connector/security_connector.cc +2 -0
  210. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  211. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +18 -11
  212. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +5 -0
  213. data/src/core/lib/security/security_connector/ssl_utils.cc +44 -23
  214. data/src/core/lib/security/security_connector/ssl_utils.h +6 -2
  215. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +27 -24
  216. data/src/core/lib/security/transport/auth_filters.h +0 -5
  217. data/src/core/lib/security/transport/client_auth_filter.cc +10 -9
  218. data/src/core/lib/security/util/json_util.cc +12 -13
  219. data/src/core/lib/slice/slice.cc +38 -1
  220. data/src/core/lib/slice/slice_internal.h +1 -0
  221. data/src/core/lib/surface/call.cc +40 -41
  222. data/src/core/lib/surface/completion_queue.cc +271 -14
  223. data/src/core/lib/surface/completion_queue.h +8 -0
  224. data/src/core/lib/surface/init.cc +2 -0
  225. data/src/core/lib/surface/server.cc +565 -632
  226. data/src/core/lib/surface/server.h +34 -12
  227. data/src/core/lib/surface/version.cc +2 -2
  228. data/src/core/lib/transport/transport.h +6 -0
  229. data/src/core/lib/uri/uri_parser.cc +8 -15
  230. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  231. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +23 -13
  232. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +2 -0
  233. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +2 -0
  234. data/src/core/tsi/ssl_transport_security.cc +108 -11
  235. data/src/core/tsi/ssl_transport_security.h +14 -2
  236. data/src/core/tsi/transport_security_interface.h +5 -0
  237. data/src/ruby/bin/math_services_pb.rb +4 -4
  238. data/src/ruby/ext/grpc/extconf.rb +5 -2
  239. data/src/ruby/ext/grpc/rb_call.c +3 -2
  240. data/src/ruby/ext/grpc/rb_call.h +4 -0
  241. data/src/ruby/ext/grpc/rb_call_credentials.c +57 -12
  242. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  243. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  244. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  245. data/src/ruby/lib/grpc/generic/interceptors.rb +1 -1
  246. data/src/ruby/lib/grpc/version.rb +1 -1
  247. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +2 -2
  248. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +5 -0
  249. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +28 -12
  250. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import2.proto +23 -0
  251. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +2 -0
  252. data/src/ruby/spec/pb/codegen/grpc/testing/same_package_service_name.proto +27 -0
  253. data/src/ruby/spec/pb/codegen/grpc/testing/same_ruby_package_service_name.proto +29 -0
  254. data/src/ruby/spec/pb/codegen/package_option_spec.rb +25 -1
  255. data/src/ruby/spec/support/services.rb +10 -4
  256. data/src/ruby/spec/user_agent_spec.rb +74 -0
  257. data/third_party/boringssl-with-bazel/err_data.c +89 -83
  258. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_bitstr.c +3 -3
  259. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_enum.c +3 -3
  260. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_int.c +1 -1
  261. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_object.c +3 -3
  262. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_time.c +2 -2
  263. data/third_party/boringssl-with-bazel/src/crypto/asn1/a_type.c +1 -1
  264. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +1 -1
  265. data/third_party/boringssl-with-bazel/src/crypto/asn1/asn_pack.c +1 -1
  266. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_enum.c +1 -1
  267. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_int.c +1 -1
  268. data/third_party/boringssl-with-bazel/src/crypto/asn1/f_string.c +1 -1
  269. data/third_party/boringssl-with-bazel/src/crypto/cipher_extra/tls_cbc.c +1 -0
  270. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/hash_to_curve.c +12 -52
  271. data/third_party/boringssl-with-bazel/src/crypto/ec_extra/internal.h +0 -22
  272. data/third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.c +143 -0
  273. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/mode_wrappers.c +17 -1
  274. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/bn/internal.h +11 -1
  275. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/internal.h +2 -1
  276. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p224-64.c +13 -11
  277. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256-x86_64.c +24 -23
  278. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/p256.c +20 -16
  279. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/simple_mul.c +2 -2
  280. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ec/util.c +3 -3
  281. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/self_check/self_check.c +62 -0
  282. data/third_party/boringssl-with-bazel/src/crypto/mem.c +29 -15
  283. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +7 -0
  284. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +36 -5
  285. data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +0 -29
  286. data/third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c +116 -363
  287. data/third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c +7 -45
  288. data/third_party/boringssl-with-bazel/src/crypto/x509/a_strex.c +4 -4
  289. data/third_party/boringssl-with-bazel/src/crypto/x509/algorithm.c +8 -0
  290. data/third_party/boringssl-with-bazel/src/crypto/x509/asn1_gen.c +4 -4
  291. data/third_party/boringssl-with-bazel/src/crypto/x509/x509.c +0 -67
  292. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +13 -6
  293. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_req.c +10 -0
  294. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +41 -0
  295. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c +4 -1
  296. data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +28 -9
  297. data/third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c +25 -0
  298. data/third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c +35 -13
  299. data/third_party/boringssl-with-bazel/src/crypto/x509/x_pubkey.c +0 -154
  300. data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c +28 -6
  301. data/third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h +5 -0
  302. data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +74 -35
  303. data/third_party/boringssl-with-bazel/src/include/openssl/aes.h +16 -4
  304. data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +22 -22
  305. data/third_party/boringssl-with-bazel/src/include/openssl/base.h +1 -1
  306. data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +69 -0
  307. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +33 -16
  308. data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +1 -10
  309. data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +789 -715
  310. data/third_party/boringssl-with-bazel/src/ssl/handoff.cc +3 -3
  311. data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +9 -2
  312. data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +2 -2
  313. data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +9 -0
  314. data/third_party/boringssl-with-bazel/src/ssl/internal.h +17 -14
  315. data/third_party/boringssl-with-bazel/src/ssl/ssl_asn1.cc +7 -7
  316. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +28 -0
  317. data/third_party/boringssl-with-bazel/src/ssl/ssl_session.cc +4 -24
  318. data/third_party/boringssl-with-bazel/src/ssl/ssl_versions.cc +5 -5
  319. data/third_party/boringssl-with-bazel/src/ssl/t1_enc.cc +45 -24
  320. data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +31 -21
  321. data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +12 -9
  322. data/third_party/re2/re2/bitmap256.h +117 -0
  323. data/third_party/re2/re2/bitstate.cc +385 -0
  324. data/third_party/re2/re2/compile.cc +1279 -0
  325. data/third_party/re2/re2/dfa.cc +2130 -0
  326. data/third_party/re2/re2/filtered_re2.cc +121 -0
  327. data/third_party/re2/re2/filtered_re2.h +109 -0
  328. data/third_party/re2/re2/mimics_pcre.cc +197 -0
  329. data/third_party/re2/re2/nfa.cc +713 -0
  330. data/third_party/re2/re2/onepass.cc +623 -0
  331. data/third_party/re2/re2/parse.cc +2464 -0
  332. data/third_party/re2/re2/perl_groups.cc +119 -0
  333. data/third_party/re2/re2/pod_array.h +55 -0
  334. data/third_party/re2/re2/prefilter.cc +710 -0
  335. data/third_party/re2/re2/prefilter.h +108 -0
  336. data/third_party/re2/re2/prefilter_tree.cc +407 -0
  337. data/third_party/re2/re2/prefilter_tree.h +139 -0
  338. data/third_party/re2/re2/prog.cc +988 -0
  339. data/third_party/re2/re2/prog.h +436 -0
  340. data/third_party/re2/re2/re2.cc +1362 -0
  341. data/third_party/re2/re2/re2.h +1002 -0
  342. data/third_party/re2/re2/regexp.cc +980 -0
  343. data/third_party/re2/re2/regexp.h +659 -0
  344. data/third_party/re2/re2/set.cc +154 -0
  345. data/third_party/re2/re2/set.h +80 -0
  346. data/third_party/re2/re2/simplify.cc +657 -0
  347. data/third_party/re2/re2/sparse_array.h +392 -0
  348. data/third_party/re2/re2/sparse_set.h +264 -0
  349. data/third_party/re2/re2/stringpiece.cc +65 -0
  350. data/third_party/re2/re2/stringpiece.h +210 -0
  351. data/third_party/re2/re2/tostring.cc +351 -0
  352. data/third_party/re2/re2/unicode_casefold.cc +582 -0
  353. data/third_party/re2/re2/unicode_casefold.h +78 -0
  354. data/third_party/re2/re2/unicode_groups.cc +6269 -0
  355. data/third_party/re2/re2/unicode_groups.h +67 -0
  356. data/third_party/re2/re2/walker-inl.h +246 -0
  357. data/third_party/re2/util/benchmark.h +156 -0
  358. data/third_party/re2/util/flags.h +26 -0
  359. data/third_party/re2/util/logging.h +109 -0
  360. data/third_party/re2/util/malloc_counter.h +19 -0
  361. data/third_party/re2/util/mix.h +41 -0
  362. data/third_party/re2/util/mutex.h +148 -0
  363. data/third_party/re2/util/pcre.cc +1025 -0
  364. data/third_party/re2/util/pcre.h +681 -0
  365. data/third_party/re2/util/rune.cc +260 -0
  366. data/third_party/re2/util/strutil.cc +149 -0
  367. data/third_party/re2/util/strutil.h +21 -0
  368. data/third_party/re2/util/test.h +50 -0
  369. data/third_party/re2/util/utf.h +44 -0
  370. data/third_party/re2/util/util.h +42 -0
  371. data/third_party/upb/upb/decode.c +467 -504
  372. data/third_party/upb/upb/encode.c +163 -121
  373. data/third_party/upb/upb/msg.c +130 -64
  374. data/third_party/upb/upb/msg.h +418 -14
  375. data/third_party/upb/upb/port_def.inc +35 -6
  376. data/third_party/upb/upb/port_undef.inc +8 -1
  377. data/third_party/upb/upb/table.c +53 -75
  378. data/third_party/upb/upb/table.int.h +11 -43
  379. data/third_party/upb/upb/upb.c +148 -124
  380. data/third_party/upb/upb/upb.h +65 -147
  381. data/third_party/upb/upb/upb.hpp +86 -0
  382. metadata +90 -30
  383. data/third_party/upb/upb/generated_util.h +0 -105
@@ -390,6 +390,14 @@ typedef struct {
390
390
  void* reserved;
391
391
  } grpc_auth_metadata_context;
392
392
 
393
+ /** Performs a deep copy from \a from to \a to. **/
394
+ GRPCAPI void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from,
395
+ grpc_auth_metadata_context* to);
396
+
397
+ /** Releases internal resources held by \a context. **/
398
+ GRPCAPI void grpc_auth_metadata_context_reset(
399
+ grpc_auth_metadata_context* context);
400
+
393
401
  /** Maximum number of metadata entries returnable by a credentials plugin via
394
402
  a synchronous return. */
395
403
  #define GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX 4
@@ -139,6 +139,9 @@ typedef enum {
139
139
  */
140
140
  typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type;
141
141
 
142
+ /** The TLS versions that are supported by the SSL stack. **/
143
+ typedef enum { TLS1_2, TLS1_3 } grpc_tls_version;
144
+
142
145
  #ifdef __cplusplus
143
146
  }
144
147
  #endif
@@ -203,18 +203,18 @@ typedef struct {
203
203
  /** Should BDP probing be performed? */
204
204
  #define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe"
205
205
  /** Minimum time between sending successive ping frames without receiving any
206
- data/header/window_update frame, Int valued, milliseconds. */
206
+ data/header frame, Int valued, milliseconds. */
207
207
  #define GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS \
208
208
  "grpc.http2.min_time_between_pings_ms"
209
209
  /** Minimum allowed time between a server receiving successive ping frames
210
- without sending any data/header/window_update frame. Int valued, milliseconds
210
+ without sending any data/header frame. Int valued, milliseconds
211
211
  */
212
212
  #define GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS \
213
213
  "grpc.http2.min_ping_interval_without_data_ms"
214
214
  /** Channel arg to override the http2 :scheme header */
215
215
  #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
216
216
  /** How many pings can we send before needing to send a
217
- data/header/window_update frame? (0 indicates that an infinite number of
217
+ data/header frame? (0 indicates that an infinite number of
218
218
  pings can be sent without sending a data frame or header frame) */
219
219
  #define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
220
220
  "grpc.http2.max_pings_without_data"
@@ -674,8 +674,10 @@ typedef struct grpc_op {
674
674
  const char** error_string;
675
675
  } recv_status_on_client;
676
676
  struct grpc_op_recv_close_on_server {
677
- /** out argument, set to 1 if the call failed in any way (seen as a
678
- cancellation on the server), or 0 if the call succeeded */
677
+ /** out argument, set to 1 if the call failed at the server for
678
+ a reason other than a non-OK status (cancel, deadline
679
+ exceeded, network failure, etc.), 0 otherwise (RPC processing ran to
680
+ completion and was able to provide any status from the server) */
679
681
  int* cancelled;
680
682
  } recv_close_on_server;
681
683
  } data;
@@ -27,13 +27,6 @@
27
27
  * - some syscalls to be made directly
28
28
  */
29
29
 
30
- /*
31
- * Defines GRPC_USE_ABSL to use Abseil Common Libraries (C++)
32
- */
33
- #ifndef GRPC_USE_ABSL
34
- #define GRPC_USE_ABSL 1
35
- #endif
36
-
37
30
  /*
38
31
  * Defines GPR_ABSEIL_SYNC to use synchronization features from Abseil
39
32
  */
@@ -112,31 +105,6 @@
112
105
  #define GPR_WINDOWS_ATOMIC 1
113
106
  #define GPR_MSVC_TLS 1
114
107
  #endif
115
- #elif defined(GPR_MANYLINUX1)
116
- // TODO(atash): manylinux1 is just another __linux__ but with ancient
117
- // libraries; it should be integrated with the `__linux__` definitions below.
118
- #define GPR_PLATFORM_STRING "manylinux"
119
- #define GPR_POSIX_CRASH_HANDLER 1
120
- #define GPR_CPU_POSIX 1
121
- #define GPR_GCC_ATOMIC 1
122
- #define GPR_GCC_TLS 1
123
- #define GPR_LINUX 1
124
- #define GPR_LINUX_LOG 1
125
- #define GPR_SUPPORT_CHANNELS_FROM_FD 1
126
- #define GPR_LINUX_ENV 1
127
- #define GPR_POSIX_TMPFILE 1
128
- #define GPR_POSIX_STRING 1
129
- #define GPR_POSIX_SUBPROCESS 1
130
- #define GPR_POSIX_SYNC 1
131
- #define GPR_POSIX_TIME 1
132
- #define GPR_HAS_PTHREAD_H 1
133
- #define GPR_GETPID_IN_UNISTD_H 1
134
- #ifdef _LP64
135
- #define GPR_ARCH_64 1
136
- #else /* _LP64 */
137
- #define GPR_ARCH_32 1
138
- #endif /* _LP64 */
139
- #include <linux/version.h>
140
108
  #elif defined(ANDROID) || defined(__ANDROID__)
141
109
  #define GPR_PLATFORM_STRING "android"
142
110
  #define GPR_ANDROID 1
@@ -21,6 +21,7 @@
21
21
  #include "absl/strings/string_view.h"
22
22
 
23
23
  #include "udpa/data/orca/v1/orca_load_report.upb.h"
24
+ #include "upb/upb.hpp"
24
25
 
25
26
  #include "src/core/lib/gprpp/map.h"
26
27
 
@@ -31,17 +32,19 @@ namespace {
31
32
  template <typename EntryType>
32
33
  std::map<absl::string_view, double, StringLess> ParseMap(
33
34
  udpa_data_orca_v1_OrcaLoadReport* msg,
34
- EntryType** (*entry_func)(udpa_data_orca_v1_OrcaLoadReport*, size_t*),
35
+ const EntryType* (*entry_func)(const udpa_data_orca_v1_OrcaLoadReport*,
36
+ size_t*),
35
37
  upb_strview (*key_func)(const EntryType*),
36
38
  double (*value_func)(const EntryType*), Arena* arena) {
37
39
  std::map<absl::string_view, double, StringLess> result;
38
- size_t size;
39
- const auto* const* entries = entry_func(msg, &size);
40
- for (size_t i = 0; i < size; ++i) {
41
- upb_strview key_view = key_func(entries[i]);
42
- char* key = static_cast<char*>(arena->Alloc(key_view.size + 1));
40
+ size_t i = UPB_MAP_BEGIN;
41
+ while (true) {
42
+ const auto* entry = entry_func(msg, &i);
43
+ if (entry == nullptr) break;
44
+ upb_strview key_view = key_func(entry);
45
+ char* key = static_cast<char*>(arena->Alloc(key_view.size));
43
46
  memcpy(key, key_view.data, key_view.size);
44
- result[absl::string_view(key, key_view.size)] = value_func(entries[i]);
47
+ result[absl::string_view(key, key_view.size)] = value_func(entry);
45
48
  }
46
49
  return result;
47
50
  }
@@ -67,12 +70,12 @@ const LoadBalancingPolicy::BackendMetricData* ParseBackendMetricData(
67
70
  udpa_data_orca_v1_OrcaLoadReport_rps(msg);
68
71
  backend_metric_data->request_cost =
69
72
  ParseMap<udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry>(
70
- msg, udpa_data_orca_v1_OrcaLoadReport_mutable_request_cost,
73
+ msg, udpa_data_orca_v1_OrcaLoadReport_request_cost_next,
71
74
  udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry_key,
72
75
  udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry_value, arena);
73
76
  backend_metric_data->utilization =
74
77
  ParseMap<udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry>(
75
- msg, udpa_data_orca_v1_OrcaLoadReport_mutable_utilization,
78
+ msg, udpa_data_orca_v1_OrcaLoadReport_utilization_next,
76
79
  udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry_key,
77
80
  udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry_value, arena);
78
81
  return backend_metric_data;
@@ -40,6 +40,7 @@
40
40
 
41
41
  #include "src/core/ext/filters/client_channel/backend_metric.h"
42
42
  #include "src/core/ext/filters/client_channel/backup_poller.h"
43
+ #include "src/core/ext/filters/client_channel/config_selector.h"
43
44
  #include "src/core/ext/filters/client_channel/global_subchannel_pool.h"
44
45
  #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
45
46
  #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
@@ -149,12 +150,16 @@ class ChannelData {
149
150
  bool received_service_config_data() const {
150
151
  return received_service_config_data_;
151
152
  }
153
+ grpc_error* resolver_transient_failure_error() const {
154
+ return resolver_transient_failure_error_;
155
+ }
152
156
  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() const {
153
157
  return retry_throttle_data_;
154
158
  }
155
159
  RefCountedPtr<ServiceConfig> service_config() const {
156
160
  return service_config_;
157
161
  }
162
+ ConfigSelector* config_selector() const { return config_selector_.get(); }
158
163
  WorkSerializer* work_serializer() const { return work_serializer_.get(); }
159
164
 
160
165
  RefCountedPtr<ConnectedSubchannel> GetConnectedSubchannelInDataPlane(
@@ -166,25 +171,14 @@ class ChannelData {
166
171
  grpc_connectivity_state* state,
167
172
  grpc_closure* on_complete,
168
173
  grpc_closure* watcher_timer_init) {
169
- auto* watcher = new ExternalConnectivityWatcher(
170
- this, pollent, state, on_complete, watcher_timer_init);
171
- {
172
- MutexLock lock(&external_watchers_mu_);
173
- // Will be deleted when the watch is complete.
174
- GPR_ASSERT(external_watchers_[on_complete] == nullptr);
175
- external_watchers_[on_complete] = watcher;
176
- }
177
- watcher->Start();
174
+ new ExternalConnectivityWatcher(this, pollent, state, on_complete,
175
+ watcher_timer_init);
178
176
  }
179
177
 
180
178
  void RemoveExternalConnectivityWatcher(grpc_closure* on_complete,
181
179
  bool cancel) {
182
- MutexLock lock(&external_watchers_mu_);
183
- auto it = external_watchers_.find(on_complete);
184
- if (it != external_watchers_.end()) {
185
- if (cancel) it->second->Cancel();
186
- external_watchers_.erase(it);
187
- }
180
+ ExternalConnectivityWatcher::RemoveWatcherFromExternalWatchersMap(
181
+ this, on_complete, cancel);
188
182
  }
189
183
 
190
184
  int NumExternalConnectivityWatchers() const {
@@ -215,13 +209,18 @@ class ChannelData {
215
209
 
216
210
  ~ExternalConnectivityWatcher();
217
211
 
218
- void Start();
212
+ // Removes the watcher from the external_watchers_ map.
213
+ static void RemoveWatcherFromExternalWatchersMap(ChannelData* chand,
214
+ grpc_closure* on_complete,
215
+ bool cancel);
219
216
 
220
217
  void Notify(grpc_connectivity_state state) override;
221
218
 
222
219
  void Cancel();
223
220
 
224
221
  private:
222
+ // Adds the watcher to state_tracker_. Consumes the ref that is passed to it
223
+ // from Start().
225
224
  void AddWatcherLocked();
226
225
  void RemoveWatcherLocked();
227
226
 
@@ -234,6 +233,29 @@ class ChannelData {
234
233
  Atomic<bool> done_{false};
235
234
  };
236
235
 
236
+ class ChannelConfigHelper
237
+ : public ResolvingLoadBalancingPolicy::ChannelConfigHelper {
238
+ public:
239
+ explicit ChannelConfigHelper(ChannelData* chand) : chand_(chand) {}
240
+
241
+ ApplyServiceConfigResult ApplyServiceConfig(
242
+ const Resolver::Result& result) override;
243
+
244
+ void ApplyConfigSelector(
245
+ bool service_config_changed,
246
+ RefCountedPtr<ConfigSelector> config_selector) override;
247
+
248
+ void ResolverTransientFailure(grpc_error* error) override;
249
+
250
+ private:
251
+ static void ProcessLbPolicy(
252
+ const Resolver::Result& resolver_result,
253
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
254
+ RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
255
+
256
+ ChannelData* chand_;
257
+ };
258
+
237
259
  ChannelData(grpc_channel_element_args* args, grpc_error** error);
238
260
  ~ChannelData();
239
261
 
@@ -241,30 +263,20 @@ class ChannelData {
241
263
  grpc_connectivity_state state, const char* reason,
242
264
  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker);
243
265
 
244
- void UpdateServiceConfigLocked(
245
- RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
246
- RefCountedPtr<ServiceConfig> service_config);
266
+ void UpdateServiceConfigInDataPlaneLocked(
267
+ bool service_config_changed,
268
+ RefCountedPtr<ConfigSelector> config_selector);
247
269
 
248
270
  void CreateResolvingLoadBalancingPolicyLocked();
249
271
 
250
272
  void DestroyResolvingLoadBalancingPolicyLocked();
251
273
 
252
- static bool ProcessResolverResultLocked(
253
- void* arg, const Resolver::Result& result,
254
- RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
255
- grpc_error** service_config_error, bool* no_valid_service_config);
256
-
257
274
  grpc_error* DoPingLocked(grpc_transport_op* op);
258
275
 
259
276
  void StartTransportOpLocked(grpc_transport_op* op);
260
277
 
261
278
  void TryToConnectLocked();
262
279
 
263
- void ProcessLbPolicy(
264
- const Resolver::Result& resolver_result,
265
- const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
266
- RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
267
-
268
280
  //
269
281
  // Fields set at construction and never modified.
270
282
  //
@@ -278,6 +290,7 @@ class ChannelData {
278
290
  grpc_core::UniquePtr<char> server_name_;
279
291
  grpc_core::UniquePtr<char> target_uri_;
280
292
  channelz::ChannelNode* channelz_node_;
293
+ ChannelConfigHelper channel_config_helper_;
281
294
 
282
295
  //
283
296
  // Fields used in the data plane. Guarded by data_plane_mu.
@@ -286,9 +299,11 @@ class ChannelData {
286
299
  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker_;
287
300
  QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks.
288
301
  // Data from service config.
302
+ grpc_error* resolver_transient_failure_error_ = GRPC_ERROR_NONE;
289
303
  bool received_service_config_data_ = false;
290
304
  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
291
305
  RefCountedPtr<ServiceConfig> service_config_;
306
+ RefCountedPtr<ConfigSelector> config_selector_;
292
307
 
293
308
  //
294
309
  // Fields used in the control plane. Guarded by work_serializer.
@@ -300,6 +315,7 @@ class ChannelData {
300
315
  ConnectivityStateTracker state_tracker_;
301
316
  grpc_core::UniquePtr<char> health_check_service_name_;
302
317
  RefCountedPtr<ServiceConfig> saved_service_config_;
318
+ RefCountedPtr<ConfigSelector> saved_config_selector_;
303
319
  bool received_first_resolver_result_ = false;
304
320
  // The number of SubchannelWrapper instances referencing a given Subchannel.
305
321
  std::map<Subchannel*, int> subchannel_refcount_map_;
@@ -332,7 +348,8 @@ class ChannelData {
332
348
  // synchronously via grpc_channel_num_external_connectivity_watchers().
333
349
  //
334
350
  mutable Mutex external_watchers_mu_;
335
- std::map<grpc_closure*, ExternalConnectivityWatcher*> external_watchers_;
351
+ std::map<grpc_closure*, RefCountedPtr<ExternalConnectivityWatcher>>
352
+ external_watchers_;
336
353
  };
337
354
 
338
355
  //
@@ -352,9 +369,6 @@ class CallData {
352
369
 
353
370
  RefCountedPtr<SubchannelCall> subchannel_call() { return subchannel_call_; }
354
371
 
355
- // Invoked by channel for queued picks once resolver results are available.
356
- void MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem);
357
-
358
372
  // Invoked by channel for queued picks when the picker is updated.
359
373
  static void PickSubchannel(void* arg, grpc_error* error);
360
374
 
@@ -388,7 +402,8 @@ class CallData {
388
402
  iterator begin() const override {
389
403
  static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
390
404
  "iterator size too large");
391
- return iterator(this, reinterpret_cast<intptr_t>(batch_->list.head));
405
+ return iterator(
406
+ this, reinterpret_cast<intptr_t>(MaybeSkipEntry(batch_->list.head)));
392
407
  }
393
408
  iterator end() const override {
394
409
  static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
@@ -405,11 +420,19 @@ class CallData {
405
420
  }
406
421
 
407
422
  private:
423
+ grpc_linked_mdelem* MaybeSkipEntry(grpc_linked_mdelem* entry) const {
424
+ if (entry != nullptr && batch_->idx.named.path == entry) {
425
+ return entry->next;
426
+ }
427
+ return entry;
428
+ }
429
+
408
430
  intptr_t IteratorHandleNext(intptr_t handle) const override {
409
431
  grpc_linked_mdelem* linked_mdelem =
410
432
  reinterpret_cast<grpc_linked_mdelem*>(handle);
411
- return reinterpret_cast<intptr_t>(linked_mdelem->next);
433
+ return reinterpret_cast<intptr_t>(MaybeSkipEntry(linked_mdelem->next));
412
434
  }
435
+
413
436
  std::pair<absl::string_view, absl::string_view> IteratorHandleGet(
414
437
  intptr_t handle) const override {
415
438
  grpc_linked_mdelem* linked_mdelem =
@@ -742,13 +765,17 @@ class CallData {
742
765
  void CreateSubchannelCall(grpc_call_element* elem);
743
766
  // Invoked when a pick is completed, on both success or failure.
744
767
  static void PickDone(void* arg, grpc_error* error);
745
- // Removes the call from the channel's list of queued picks.
746
- void RemoveCallFromQueuedPicksLocked(grpc_call_element* elem);
747
- // Adds the call to the channel's list of queued picks.
748
- void AddCallToQueuedPicksLocked(grpc_call_element* elem);
768
+ // Removes the call from the channel's list of queued picks if present.
769
+ void MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem);
770
+ // Adds the call to the channel's list of queued picks if not already present.
771
+ void MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem);
749
772
  // Applies service config to the call. Must be invoked once we know
750
773
  // that the resolver has returned results to the channel.
751
- void ApplyServiceConfigToCallLocked(grpc_call_element* elem);
774
+ // If an error is returned, the error indicates the status with which
775
+ // the call should be failed.
776
+ grpc_error* ApplyServiceConfigToCallLocked(
777
+ grpc_call_element* elem, grpc_metadata_batch* initial_metadata);
778
+ void MaybeInvokeConfigSelectorCommitCallback();
752
779
 
753
780
  // State for handling deadlines.
754
781
  // The code in deadline_filter.c requires this to be the first field.
@@ -769,6 +796,7 @@ class CallData {
769
796
  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
770
797
  const ClientChannelMethodParsedConfig* method_params_ = nullptr;
771
798
  std::map<const char*, absl::string_view> call_attributes_;
799
+ std::function<void()> on_call_committed_;
772
800
 
773
801
  RefCountedPtr<SubchannelCall> subchannel_call_;
774
802
 
@@ -1141,6 +1169,21 @@ ChannelData::ExternalConnectivityWatcher::ExternalConnectivityWatcher(
1141
1169
  grpc_polling_entity_add_to_pollset_set(&pollent_,
1142
1170
  chand_->interested_parties_);
1143
1171
  GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ExternalConnectivityWatcher");
1172
+ {
1173
+ MutexLock lock(&chand_->external_watchers_mu_);
1174
+ // Will be deleted when the watch is complete.
1175
+ GPR_ASSERT(chand->external_watchers_[on_complete] == nullptr);
1176
+ // Store a ref to the watcher in the external_watchers_ map.
1177
+ chand->external_watchers_[on_complete] =
1178
+ Ref(DEBUG_LOCATION, "AddWatcherToExternalWatchersMapLocked");
1179
+ }
1180
+ // Pass the ref from creating the object to Start().
1181
+ chand_->work_serializer_->Run(
1182
+ [this]() {
1183
+ // The ref is passed to AddWatcherLocked().
1184
+ AddWatcherLocked();
1185
+ },
1186
+ DEBUG_LOCATION);
1144
1187
  }
1145
1188
 
1146
1189
  ChannelData::ExternalConnectivityWatcher::~ExternalConnectivityWatcher() {
@@ -1150,9 +1193,22 @@ ChannelData::ExternalConnectivityWatcher::~ExternalConnectivityWatcher() {
1150
1193
  "ExternalConnectivityWatcher");
1151
1194
  }
1152
1195
 
1153
- void ChannelData::ExternalConnectivityWatcher::Start() {
1154
- chand_->work_serializer_->Run([this]() { AddWatcherLocked(); },
1155
- DEBUG_LOCATION);
1196
+ void ChannelData::ExternalConnectivityWatcher::
1197
+ RemoveWatcherFromExternalWatchersMap(ChannelData* chand,
1198
+ grpc_closure* on_complete,
1199
+ bool cancel) {
1200
+ RefCountedPtr<ExternalConnectivityWatcher> watcher;
1201
+ {
1202
+ MutexLock lock(&chand->external_watchers_mu_);
1203
+ auto it = chand->external_watchers_.find(on_complete);
1204
+ if (it != chand->external_watchers_.end()) {
1205
+ watcher = std::move(it->second);
1206
+ chand->external_watchers_.erase(it);
1207
+ }
1208
+ }
1209
+ // watcher->Cancel() will hop into the WorkSerializer, so we have to unlock
1210
+ // the mutex before calling it.
1211
+ if (watcher != nullptr && cancel) watcher->Cancel();
1156
1212
  }
1157
1213
 
1158
1214
  void ChannelData::ExternalConnectivityWatcher::Notify(
@@ -1190,7 +1246,7 @@ void ChannelData::ExternalConnectivityWatcher::Cancel() {
1190
1246
 
1191
1247
  void ChannelData::ExternalConnectivityWatcher::AddWatcherLocked() {
1192
1248
  Closure::Run(DEBUG_LOCATION, watcher_timer_init_, GRPC_ERROR_NONE);
1193
- // Add new watcher.
1249
+ // Add new watcher. Pass the ref of the object from creation to OrphanablePtr.
1194
1250
  chand_->state_tracker_.AddWatcher(
1195
1251
  initial_state_, OrphanablePtr<ConnectivityStateWatcherInterface>(this));
1196
1252
  }
@@ -1335,6 +1391,180 @@ class ChannelData::ClientChannelControlHelper
1335
1391
  ChannelData* chand_;
1336
1392
  };
1337
1393
 
1394
+ //
1395
+ // ChannelData::ChannelConfigHelper
1396
+ //
1397
+
1398
+ // Synchronous callback from ResolvingLoadBalancingPolicy to process a
1399
+ // resolver result update.
1400
+ ChannelData::ChannelConfigHelper::ApplyServiceConfigResult
1401
+ ChannelData::ChannelConfigHelper::ApplyServiceConfig(
1402
+ const Resolver::Result& result) {
1403
+ ApplyServiceConfigResult service_config_result;
1404
+ RefCountedPtr<ServiceConfig> service_config;
1405
+ // If resolver did not return a service config or returned an invalid service
1406
+ // config, we need a fallback service config.
1407
+ if (result.service_config_error != GRPC_ERROR_NONE) {
1408
+ // If the service config was invalid, then fallback to the saved service
1409
+ // config. If there is no saved config either, use the default service
1410
+ // config.
1411
+ if (chand_->saved_service_config_ != nullptr) {
1412
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1413
+ gpr_log(GPR_INFO,
1414
+ "chand=%p: resolver returned invalid service config. "
1415
+ "Continuing to use previous service config.",
1416
+ chand_);
1417
+ }
1418
+ service_config = chand_->saved_service_config_;
1419
+ } else if (chand_->default_service_config_ != nullptr) {
1420
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1421
+ gpr_log(GPR_INFO,
1422
+ "chand=%p: resolver returned invalid service config. Using "
1423
+ "default service config provided by client API.",
1424
+ chand_);
1425
+ }
1426
+ service_config = chand_->default_service_config_;
1427
+ }
1428
+ } else if (result.service_config == nullptr) {
1429
+ if (chand_->default_service_config_ != nullptr) {
1430
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1431
+ gpr_log(GPR_INFO,
1432
+ "chand=%p: resolver returned no service config. Using default "
1433
+ "service config provided by client API.",
1434
+ chand_);
1435
+ }
1436
+ service_config = chand_->default_service_config_;
1437
+ }
1438
+ } else {
1439
+ service_config = result.service_config;
1440
+ }
1441
+ service_config_result.service_config_error =
1442
+ GRPC_ERROR_REF(result.service_config_error);
1443
+ if (service_config == nullptr &&
1444
+ result.service_config_error != GRPC_ERROR_NONE) {
1445
+ service_config_result.no_valid_service_config = true;
1446
+ return service_config_result;
1447
+ }
1448
+ // Process service config.
1449
+ grpc_core::UniquePtr<char> service_config_json;
1450
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1451
+ nullptr;
1452
+ if (service_config != nullptr) {
1453
+ parsed_service_config =
1454
+ static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1455
+ service_config->GetGlobalParsedConfig(
1456
+ internal::ClientChannelServiceConfigParser::ParserIndex()));
1457
+ }
1458
+ // Check if the config has changed.
1459
+ service_config_result.service_config_changed =
1460
+ ((service_config == nullptr) !=
1461
+ (chand_->saved_service_config_ == nullptr)) ||
1462
+ (service_config != nullptr &&
1463
+ service_config->json_string() !=
1464
+ chand_->saved_service_config_->json_string());
1465
+ if (service_config_result.service_config_changed) {
1466
+ service_config_json.reset(gpr_strdup(
1467
+ service_config != nullptr ? service_config->json_string().c_str()
1468
+ : ""));
1469
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1470
+ gpr_log(GPR_INFO,
1471
+ "chand=%p: resolver returned updated service config: \"%s\"",
1472
+ chand_, service_config_json.get());
1473
+ }
1474
+ // Save health check service name.
1475
+ if (service_config != nullptr) {
1476
+ chand_->health_check_service_name_.reset(
1477
+ gpr_strdup(parsed_service_config->health_check_service_name()));
1478
+ } else {
1479
+ chand_->health_check_service_name_.reset();
1480
+ }
1481
+ // Update health check service name used by existing subchannel wrappers.
1482
+ for (auto* subchannel_wrapper : chand_->subchannel_wrappers_) {
1483
+ subchannel_wrapper->UpdateHealthCheckServiceName(
1484
+ grpc_core::UniquePtr<char>(
1485
+ gpr_strdup(chand_->health_check_service_name_.get())));
1486
+ }
1487
+ // Save service config.
1488
+ chand_->saved_service_config_ = std::move(service_config);
1489
+ }
1490
+ // Find LB policy config.
1491
+ ProcessLbPolicy(result, parsed_service_config,
1492
+ &service_config_result.lb_policy_config);
1493
+ grpc_core::UniquePtr<char> lb_policy_name(
1494
+ gpr_strdup((service_config_result.lb_policy_config)->name()));
1495
+ // Swap out the data used by GetChannelInfo().
1496
+ {
1497
+ MutexLock lock(&chand_->info_mu_);
1498
+ chand_->info_lb_policy_name_ = std::move(lb_policy_name);
1499
+ if (service_config_json != nullptr) {
1500
+ chand_->info_service_config_json_ = std::move(service_config_json);
1501
+ }
1502
+ }
1503
+ // Return results.
1504
+ return service_config_result;
1505
+ }
1506
+
1507
+ void ChannelData::ChannelConfigHelper::ApplyConfigSelector(
1508
+ bool service_config_changed,
1509
+ RefCountedPtr<ConfigSelector> config_selector) {
1510
+ chand_->UpdateServiceConfigInDataPlaneLocked(service_config_changed,
1511
+ std::move(config_selector));
1512
+ }
1513
+
1514
+ void ChannelData::ChannelConfigHelper::ResolverTransientFailure(
1515
+ grpc_error* error) {
1516
+ MutexLock lock(&chand_->data_plane_mu_);
1517
+ GRPC_ERROR_UNREF(chand_->resolver_transient_failure_error_);
1518
+ chand_->resolver_transient_failure_error_ = error;
1519
+ }
1520
+
1521
+ void ChannelData::ChannelConfigHelper::ProcessLbPolicy(
1522
+ const Resolver::Result& resolver_result,
1523
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
1524
+ RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
1525
+ // Prefer the LB policy config found in the service config.
1526
+ if (parsed_service_config != nullptr &&
1527
+ parsed_service_config->parsed_lb_config() != nullptr) {
1528
+ *lb_policy_config = parsed_service_config->parsed_lb_config();
1529
+ return;
1530
+ }
1531
+ // Try the deprecated LB policy name from the service config.
1532
+ // If not, try the setting from channel args.
1533
+ const char* policy_name = nullptr;
1534
+ if (parsed_service_config != nullptr &&
1535
+ !parsed_service_config->parsed_deprecated_lb_policy().empty()) {
1536
+ policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
1537
+ } else {
1538
+ const grpc_arg* channel_arg =
1539
+ grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
1540
+ policy_name = grpc_channel_arg_get_string(channel_arg);
1541
+ }
1542
+ // Use pick_first if nothing was specified and we didn't select grpclb
1543
+ // above.
1544
+ if (policy_name == nullptr) policy_name = "pick_first";
1545
+ // Now that we have the policy name, construct an empty config for it.
1546
+ Json config_json = Json::Array{Json::Object{
1547
+ {policy_name, Json::Object{}},
1548
+ }};
1549
+ grpc_error* parse_error = GRPC_ERROR_NONE;
1550
+ *lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
1551
+ config_json, &parse_error);
1552
+ // The policy name came from one of three places:
1553
+ // - The deprecated loadBalancingPolicy field in the service config,
1554
+ // in which case the code in ClientChannelServiceConfigParser
1555
+ // already verified that the policy does not require a config.
1556
+ // - One of the hard-coded values here, all of which are known to not
1557
+ // require a config.
1558
+ // - A channel arg, in which case the application did something that
1559
+ // is a misuse of our API.
1560
+ // In the first two cases, these assertions will always be true. In
1561
+ // the last case, this is probably fine for now.
1562
+ // TODO(roth): If the last case becomes a problem, add better error
1563
+ // handling here.
1564
+ GPR_ASSERT(*lb_policy_config != nullptr);
1565
+ GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
1566
+ }
1567
+
1338
1568
  //
1339
1569
  // ChannelData implementation
1340
1570
  //
@@ -1393,6 +1623,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
1393
1623
  client_channel_factory_(
1394
1624
  ClientChannelFactory::GetFromChannelArgs(args->channel_args)),
1395
1625
  channelz_node_(GetChannelzNode(args->channel_args)),
1626
+ channel_config_helper_(this),
1396
1627
  work_serializer_(std::make_shared<WorkSerializer>()),
1397
1628
  interested_parties_(grpc_pollset_set_create()),
1398
1629
  subchannel_pool_(GetSubchannelPool(args->channel_args)),
@@ -1461,6 +1692,7 @@ ChannelData::~ChannelData() {
1461
1692
  }
1462
1693
  DestroyResolvingLoadBalancingPolicyLocked();
1463
1694
  grpc_channel_args_destroy(channel_args_);
1695
+ GRPC_ERROR_UNREF(resolver_transient_failure_error_);
1464
1696
  // Stop backup polling.
1465
1697
  grpc_client_channel_stop_backup_polling(interested_parties_);
1466
1698
  grpc_pollset_set_destroy(interested_parties_);
@@ -1475,6 +1707,7 @@ void ChannelData::UpdateStateAndPickerLocked(
1475
1707
  if (picker_ == nullptr) {
1476
1708
  health_check_service_name_.reset();
1477
1709
  saved_service_config_.reset();
1710
+ saved_config_selector_.reset();
1478
1711
  received_first_resolver_result_ = false;
1479
1712
  }
1480
1713
  // Update connectivity state.
@@ -1497,9 +1730,11 @@ void ChannelData::UpdateStateAndPickerLocked(
1497
1730
  // - refs to subchannel wrappers in the keys of pending_subchannel_updates_
1498
1731
  // - ref stored in retry_throttle_data_
1499
1732
  // - ref stored in service_config_
1733
+ // - ref stored in config_selector_
1500
1734
  // - ownership of the existing picker in picker_
1501
1735
  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_to_unref;
1502
1736
  RefCountedPtr<ServiceConfig> service_config_to_unref;
1737
+ RefCountedPtr<ConfigSelector> config_selector_to_unref;
1503
1738
  {
1504
1739
  MutexLock lock(&data_plane_mu_);
1505
1740
  // Handle subchannel updates.
@@ -1524,6 +1759,7 @@ void ChannelData::UpdateStateAndPickerLocked(
1524
1759
  // Note: We save the objects to unref until after the lock is released.
1525
1760
  retry_throttle_data_to_unref = std::move(retry_throttle_data_);
1526
1761
  service_config_to_unref = std::move(service_config_);
1762
+ config_selector_to_unref = std::move(config_selector_);
1527
1763
  }
1528
1764
  // Re-process queued picks.
1529
1765
  for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
@@ -1540,24 +1776,72 @@ void ChannelData::UpdateStateAndPickerLocked(
1540
1776
  pending_subchannel_updates_.clear();
1541
1777
  }
1542
1778
 
1543
- void ChannelData::UpdateServiceConfigLocked(
1544
- RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
1545
- RefCountedPtr<ServiceConfig> service_config) {
1779
+ void ChannelData::UpdateServiceConfigInDataPlaneLocked(
1780
+ bool service_config_changed,
1781
+ RefCountedPtr<ConfigSelector> config_selector) {
1782
+ // Check if ConfigSelector has changed.
1783
+ const bool config_selector_changed =
1784
+ saved_config_selector_ != config_selector;
1785
+ saved_config_selector_ = config_selector;
1786
+ // We want to set the service config at least once, even if the
1787
+ // resolver does not return a config, because that ensures that we
1788
+ // disable retries if they are not enabled in the service config.
1789
+ // TODO(roth): Consider removing the received_first_resolver_result_ check
1790
+ // when we implement transparent retries.
1791
+ if (!service_config_changed && !config_selector_changed &&
1792
+ received_first_resolver_result_) {
1793
+ return;
1794
+ }
1795
+ received_first_resolver_result_ = true;
1796
+ // Get retry throttle data from service config.
1797
+ RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
1798
+ if (saved_service_config_ != nullptr) {
1799
+ const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1800
+ static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1801
+ saved_service_config_->GetGlobalParsedConfig(
1802
+ internal::ClientChannelServiceConfigParser::ParserIndex()));
1803
+ if (parsed_service_config != nullptr) {
1804
+ absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
1805
+ retry_throttle_config = parsed_service_config->retry_throttling();
1806
+ if (retry_throttle_config.has_value()) {
1807
+ retry_throttle_data =
1808
+ internal::ServerRetryThrottleMap::GetDataForServer(
1809
+ server_name_.get(),
1810
+ retry_throttle_config.value().max_milli_tokens,
1811
+ retry_throttle_config.value().milli_token_ratio);
1812
+ }
1813
+ }
1814
+ }
1815
+ // Create default config selector if not provided by resolver.
1816
+ if (config_selector == nullptr) {
1817
+ config_selector =
1818
+ MakeRefCounted<DefaultConfigSelector>(saved_service_config_);
1819
+ }
1546
1820
  // Grab data plane lock to update service config.
1547
1821
  //
1548
1822
  // We defer unreffing the old values (and deallocating memory) until
1549
1823
  // after releasing the lock to keep the critical section small.
1824
+ RefCountedPtr<ServiceConfig> service_config_to_unref = saved_service_config_;
1825
+ RefCountedPtr<ConfigSelector> config_selector_to_unref =
1826
+ std::move(config_selector);
1550
1827
  {
1551
1828
  MutexLock lock(&data_plane_mu_);
1829
+ GRPC_ERROR_UNREF(resolver_transient_failure_error_);
1830
+ resolver_transient_failure_error_ = GRPC_ERROR_NONE;
1552
1831
  // Update service config.
1553
1832
  received_service_config_data_ = true;
1554
1833
  // Old values will be unreffed after lock is released.
1555
1834
  retry_throttle_data_.swap(retry_throttle_data);
1556
- service_config_.swap(service_config);
1557
- // Apply service config to queued picks.
1835
+ service_config_.swap(service_config_to_unref);
1836
+ config_selector_.swap(config_selector_to_unref);
1837
+ // Re-process queued picks.
1558
1838
  for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
1559
- CallData* calld = static_cast<CallData*>(pick->elem->call_data);
1560
- calld->MaybeApplyServiceConfigToCallLocked(pick->elem);
1839
+ grpc_call_element* elem = pick->elem;
1840
+ CallData* calld = static_cast<CallData*>(elem->call_data);
1841
+ grpc_error* error = GRPC_ERROR_NONE;
1842
+ if (calld->PickSubchannelLocked(elem, &error)) {
1843
+ calld->AsyncPickDone(elem, error);
1844
+ }
1561
1845
  }
1562
1846
  }
1563
1847
  // Old values will be unreffed after lock is released when they go out
@@ -1574,7 +1858,7 @@ void ChannelData::CreateResolvingLoadBalancingPolicyLocked() {
1574
1858
  grpc_core::UniquePtr<char> target_uri(gpr_strdup(target_uri_.get()));
1575
1859
  resolving_lb_policy_.reset(new ResolvingLoadBalancingPolicy(
1576
1860
  std::move(lb_args), &grpc_client_channel_routing_trace,
1577
- std::move(target_uri), ProcessResolverResultLocked, this));
1861
+ std::move(target_uri), &channel_config_helper_));
1578
1862
  grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
1579
1863
  interested_parties_);
1580
1864
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
@@ -1591,180 +1875,6 @@ void ChannelData::DestroyResolvingLoadBalancingPolicyLocked() {
1591
1875
  }
1592
1876
  }
1593
1877
 
1594
- void ChannelData::ProcessLbPolicy(
1595
- const Resolver::Result& resolver_result,
1596
- const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
1597
- RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
1598
- // Prefer the LB policy config found in the service config.
1599
- if (parsed_service_config != nullptr &&
1600
- parsed_service_config->parsed_lb_config() != nullptr) {
1601
- *lb_policy_config = parsed_service_config->parsed_lb_config();
1602
- return;
1603
- }
1604
- // Try the deprecated LB policy name from the service config.
1605
- // If not, try the setting from channel args.
1606
- const char* policy_name = nullptr;
1607
- if (parsed_service_config != nullptr &&
1608
- !parsed_service_config->parsed_deprecated_lb_policy().empty()) {
1609
- policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
1610
- } else {
1611
- const grpc_arg* channel_arg =
1612
- grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
1613
- policy_name = grpc_channel_arg_get_string(channel_arg);
1614
- }
1615
- // Use pick_first if nothing was specified and we didn't select grpclb
1616
- // above.
1617
- if (policy_name == nullptr) policy_name = "pick_first";
1618
- // Now that we have the policy name, construct an empty config for it.
1619
- Json config_json = Json::Array{Json::Object{
1620
- {policy_name, Json::Object{}},
1621
- }};
1622
- grpc_error* parse_error = GRPC_ERROR_NONE;
1623
- *lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
1624
- config_json, &parse_error);
1625
- // The policy name came from one of three places:
1626
- // - The deprecated loadBalancingPolicy field in the service config,
1627
- // in which case the code in ClientChannelServiceConfigParser
1628
- // already verified that the policy does not require a config.
1629
- // - One of the hard-coded values here, all of which are known to not
1630
- // require a config.
1631
- // - A channel arg, in which case the application did something that
1632
- // is a misuse of our API.
1633
- // In the first two cases, these assertions will always be true. In
1634
- // the last case, this is probably fine for now.
1635
- // TODO(roth): If the last case becomes a problem, add better error
1636
- // handling here.
1637
- GPR_ASSERT(*lb_policy_config != nullptr);
1638
- GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
1639
- }
1640
-
1641
- // Synchronous callback from ResolvingLoadBalancingPolicy to process a
1642
- // resolver result update.
1643
- bool ChannelData::ProcessResolverResultLocked(
1644
- void* arg, const Resolver::Result& result,
1645
- RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config,
1646
- grpc_error** service_config_error, bool* no_valid_service_config) {
1647
- ChannelData* chand = static_cast<ChannelData*>(arg);
1648
- RefCountedPtr<ServiceConfig> service_config;
1649
- // If resolver did not return a service config or returned an invalid service
1650
- // config, we need a fallback service config.
1651
- if (result.service_config_error != GRPC_ERROR_NONE) {
1652
- // If the service config was invalid, then fallback to the saved service
1653
- // config. If there is no saved config either, use the default service
1654
- // config.
1655
- if (chand->saved_service_config_ != nullptr) {
1656
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1657
- gpr_log(GPR_INFO,
1658
- "chand=%p: resolver returned invalid service config. "
1659
- "Continuing to use previous service config.",
1660
- chand);
1661
- }
1662
- service_config = chand->saved_service_config_;
1663
- } else if (chand->default_service_config_ != nullptr) {
1664
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1665
- gpr_log(GPR_INFO,
1666
- "chand=%p: resolver returned invalid service config. Using "
1667
- "default service config provided by client API.",
1668
- chand);
1669
- }
1670
- service_config = chand->default_service_config_;
1671
- }
1672
- } else if (result.service_config == nullptr) {
1673
- if (chand->default_service_config_ != nullptr) {
1674
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1675
- gpr_log(GPR_INFO,
1676
- "chand=%p: resolver returned no service config. Using default "
1677
- "service config provided by client API.",
1678
- chand);
1679
- }
1680
- service_config = chand->default_service_config_;
1681
- }
1682
- } else {
1683
- service_config = result.service_config;
1684
- }
1685
- *service_config_error = GRPC_ERROR_REF(result.service_config_error);
1686
- if (service_config == nullptr &&
1687
- result.service_config_error != GRPC_ERROR_NONE) {
1688
- *no_valid_service_config = true;
1689
- return false;
1690
- }
1691
- // Process service config.
1692
- grpc_core::UniquePtr<char> service_config_json;
1693
- const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
1694
- nullptr;
1695
- if (service_config != nullptr) {
1696
- parsed_service_config =
1697
- static_cast<const internal::ClientChannelGlobalParsedConfig*>(
1698
- service_config->GetGlobalParsedConfig(
1699
- internal::ClientChannelServiceConfigParser::ParserIndex()));
1700
- }
1701
- // Check if the config has changed.
1702
- const bool service_config_changed =
1703
- ((service_config == nullptr) !=
1704
- (chand->saved_service_config_ == nullptr)) ||
1705
- (service_config != nullptr &&
1706
- service_config->json_string() !=
1707
- chand->saved_service_config_->json_string());
1708
- if (service_config_changed) {
1709
- service_config_json.reset(gpr_strdup(
1710
- service_config != nullptr ? service_config->json_string().c_str()
1711
- : ""));
1712
- if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
1713
- gpr_log(GPR_INFO,
1714
- "chand=%p: resolver returned updated service config: \"%s\"",
1715
- chand, service_config_json.get());
1716
- }
1717
- // Save health check service name.
1718
- if (service_config != nullptr) {
1719
- chand->health_check_service_name_.reset(
1720
- gpr_strdup(parsed_service_config->health_check_service_name()));
1721
- } else {
1722
- chand->health_check_service_name_.reset();
1723
- }
1724
- // Update health check service name used by existing subchannel wrappers.
1725
- for (auto* subchannel_wrapper : chand->subchannel_wrappers_) {
1726
- subchannel_wrapper->UpdateHealthCheckServiceName(
1727
- grpc_core::UniquePtr<char>(
1728
- gpr_strdup(chand->health_check_service_name_.get())));
1729
- }
1730
- // Save service config.
1731
- chand->saved_service_config_ = std::move(service_config);
1732
- }
1733
- // We want to set the service config at least once. This should not really be
1734
- // needed, but we are doing it as a defensive approach. This can be removed,
1735
- // if we feel it is unnecessary.
1736
- if (service_config_changed || !chand->received_first_resolver_result_) {
1737
- chand->received_first_resolver_result_ = true;
1738
- RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
1739
- if (parsed_service_config != nullptr) {
1740
- absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
1741
- retry_throttle_config = parsed_service_config->retry_throttling();
1742
- if (retry_throttle_config.has_value()) {
1743
- retry_throttle_data =
1744
- internal::ServerRetryThrottleMap::GetDataForServer(
1745
- chand->server_name_.get(),
1746
- retry_throttle_config.value().max_milli_tokens,
1747
- retry_throttle_config.value().milli_token_ratio);
1748
- }
1749
- }
1750
- chand->UpdateServiceConfigLocked(std::move(retry_throttle_data),
1751
- chand->saved_service_config_);
1752
- }
1753
- chand->ProcessLbPolicy(result, parsed_service_config, lb_policy_config);
1754
- grpc_core::UniquePtr<char> lb_policy_name(
1755
- gpr_strdup((*lb_policy_config)->name()));
1756
- // Swap out the data used by GetChannelInfo().
1757
- {
1758
- MutexLock lock(&chand->info_mu_);
1759
- chand->info_lb_policy_name_ = std::move(lb_policy_name);
1760
- if (service_config_json != nullptr) {
1761
- chand->info_service_config_json_ = std::move(service_config_json);
1762
- }
1763
- }
1764
- // Return results.
1765
- return service_config_changed;
1766
- }
1767
-
1768
1878
  grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) {
1769
1879
  if (state_tracker_.state() != GRPC_CHANNEL_READY) {
1770
1880
  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected");
@@ -2807,6 +2917,7 @@ void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) {
2807
2917
  }
2808
2918
  // Received valid initial metadata, so commit the call.
2809
2919
  calld->RetryCommit(elem, retry_state);
2920
+ calld->MaybeInvokeConfigSelectorCommitCallback();
2810
2921
  // Invoke the callback to return the result to the surface.
2811
2922
  // Manually invoking a callback function; it does not take ownership of error.
2812
2923
  calld->InvokeRecvInitialMetadataCallback(batch_data, error);
@@ -2893,6 +3004,7 @@ void CallData::RecvMessageReady(void* arg, grpc_error* error) {
2893
3004
  }
2894
3005
  // Received a valid message, so commit the call.
2895
3006
  calld->RetryCommit(elem, retry_state);
3007
+ calld->MaybeInvokeConfigSelectorCommitCallback();
2896
3008
  // Invoke the callback to return the result to the surface.
2897
3009
  // Manually invoking a callback function; it does not take ownership of error.
2898
3010
  calld->InvokeRecvMessageCallback(batch_data, error);
@@ -3094,6 +3206,7 @@ void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
3094
3206
  }
3095
3207
  // Not retrying, so commit the call.
3096
3208
  calld->RetryCommit(elem, retry_state);
3209
+ calld->MaybeInvokeConfigSelectorCommitCallback();
3097
3210
  // Run any necessary closures.
3098
3211
  calld->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error));
3099
3212
  }
@@ -3716,7 +3829,7 @@ class CallData::QueuedPickCanceller {
3716
3829
  }
3717
3830
  if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) {
3718
3831
  // Remove pick from list of queued picks.
3719
- calld->RemoveCallFromQueuedPicksLocked(self->elem_);
3832
+ calld->MaybeRemoveCallFromQueuedPicksLocked(self->elem_);
3720
3833
  // Fail pending batches on the call.
3721
3834
  calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error),
3722
3835
  YieldCallCombinerIfPendingBatchesFound);
@@ -3729,7 +3842,8 @@ class CallData::QueuedPickCanceller {
3729
3842
  grpc_closure closure_;
3730
3843
  };
3731
3844
 
3732
- void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
3845
+ void CallData::MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
3846
+ if (!pick_queued_) return;
3733
3847
  auto* chand = static_cast<ChannelData*>(elem->channel_data);
3734
3848
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
3735
3849
  gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list",
@@ -3741,7 +3855,8 @@ void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
3741
3855
  pick_canceller_ = nullptr;
3742
3856
  }
3743
3857
 
3744
- void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) {
3858
+ void CallData::MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem) {
3859
+ if (pick_queued_) return;
3745
3860
  auto* chand = static_cast<ChannelData*>(elem->channel_data);
3746
3861
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
3747
3862
  gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand,
@@ -3754,23 +3869,29 @@ void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) {
3754
3869
  pick_canceller_ = new QueuedPickCanceller(elem);
3755
3870
  }
3756
3871
 
3757
- void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) {
3872
+ grpc_error* CallData::ApplyServiceConfigToCallLocked(
3873
+ grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
3758
3874
  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
3759
3875
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
3760
3876
  gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
3761
3877
  chand, this);
3762
3878
  }
3879
+ ConfigSelector* config_selector = chand->config_selector();
3763
3880
  auto service_config = chand->service_config();
3764
3881
  if (service_config != nullptr) {
3882
+ // Use the ConfigSelector to determine the config for the call.
3883
+ ConfigSelector::CallConfig call_config =
3884
+ config_selector->GetCallConfig({&path_, initial_metadata, arena_});
3885
+ if (call_config.error != GRPC_ERROR_NONE) return call_config.error;
3886
+ call_attributes_ = std::move(call_config.call_attributes);
3887
+ on_call_committed_ = std::move(call_config.on_call_committed);
3765
3888
  // Create a ServiceConfigCallData for the call. This stores a ref to the
3766
3889
  // ServiceConfig and caches the right set of parsed configs to use for
3767
3890
  // the call. The MethodConfig will store itself in the call context,
3768
3891
  // so that it can be accessed by filters in the subchannel, and it
3769
3892
  // will be cleaned up when the call ends.
3770
- const auto* method_params_vector =
3771
- service_config->GetMethodParsedConfigVector(path_);
3772
3893
  auto* service_config_call_data = arena_->New<ServiceConfigCallData>(
3773
- std::move(service_config), method_params_vector, call_context_);
3894
+ std::move(service_config), call_config.method_configs, call_context_);
3774
3895
  // Apply our own method params to the call.
3775
3896
  method_params_ = static_cast<ClientChannelMethodParsedConfig*>(
3776
3897
  service_config_call_data->GetMethodParsedConfig(
@@ -3812,16 +3933,13 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) {
3812
3933
  if (method_params_ == nullptr || method_params_->retry_policy() == nullptr) {
3813
3934
  enable_retries_ = false;
3814
3935
  }
3936
+ return GRPC_ERROR_NONE;
3815
3937
  }
3816
3938
 
3817
- void CallData::MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem) {
3818
- ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
3819
- // Apply service config data to the call only once, and only if the
3820
- // channel has the data available.
3821
- if (GPR_LIKELY(chand->received_service_config_data() &&
3822
- !service_config_applied_)) {
3823
- service_config_applied_ = true;
3824
- ApplyServiceConfigToCallLocked(elem);
3939
+ void CallData::MaybeInvokeConfigSelectorCommitCallback() {
3940
+ if (on_call_committed_ != nullptr) {
3941
+ on_call_committed_();
3942
+ on_call_committed_ = nullptr;
3825
3943
  }
3826
3944
  }
3827
3945
 
@@ -3882,11 +4000,45 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
3882
4000
  GRPC_ERROR_NONE);
3883
4001
  // Queue the pick, so that it will be attempted once the channel
3884
4002
  // becomes connected.
3885
- AddCallToQueuedPicksLocked(elem);
4003
+ MaybeAddCallToQueuedPicksLocked(elem);
4004
+ return false;
4005
+ }
4006
+ grpc_metadata_batch* initial_metadata_batch =
4007
+ seen_send_initial_metadata_
4008
+ ? &send_initial_metadata_
4009
+ : pending_batches_[0]
4010
+ .batch->payload->send_initial_metadata.send_initial_metadata;
4011
+ // Grab initial metadata flags so that we can check later if the call has
4012
+ // wait_for_ready enabled.
4013
+ const uint32_t send_initial_metadata_flags =
4014
+ seen_send_initial_metadata_ ? send_initial_metadata_flags_
4015
+ : pending_batches_[0]
4016
+ .batch->payload->send_initial_metadata
4017
+ .send_initial_metadata_flags;
4018
+ // Avoid picking if we haven't yet received service config data.
4019
+ if (GPR_UNLIKELY(!chand->received_service_config_data())) {
4020
+ // If the resolver returned transient failure before returning the
4021
+ // first service config, fail any non-wait_for_ready calls.
4022
+ grpc_error* resolver_error = chand->resolver_transient_failure_error();
4023
+ if (resolver_error != GRPC_ERROR_NONE &&
4024
+ (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) ==
4025
+ 0) {
4026
+ MaybeRemoveCallFromQueuedPicksLocked(elem);
4027
+ *error = GRPC_ERROR_REF(resolver_error);
4028
+ return true;
4029
+ }
4030
+ // Either the resolver has not yet returned a result, or it has
4031
+ // returned transient failure but the call is wait_for_ready. In
4032
+ // either case, queue the call.
4033
+ MaybeAddCallToQueuedPicksLocked(elem);
3886
4034
  return false;
3887
4035
  }
3888
- // Apply service config to call if needed.
3889
- MaybeApplyServiceConfigToCallLocked(elem);
4036
+ // Apply service config to call if not yet applied.
4037
+ if (GPR_LIKELY(!service_config_applied_)) {
4038
+ service_config_applied_ = true;
4039
+ *error = ApplyServiceConfigToCallLocked(elem, initial_metadata_batch);
4040
+ if (*error != GRPC_ERROR_NONE) return true;
4041
+ }
3890
4042
  // If this is a retry, use the send_initial_metadata payload that
3891
4043
  // we've cached; otherwise, use the pending batch. The
3892
4044
  // send_initial_metadata batch will be the first pending batch in the
@@ -3898,21 +4050,10 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
3898
4050
  // subchannel's copy of the metadata batch (which is copied for each
3899
4051
  // attempt) to the LB policy instead the one from the parent channel.
3900
4052
  LoadBalancingPolicy::PickArgs pick_args;
4053
+ pick_args.path = StringViewFromSlice(path_);
3901
4054
  pick_args.call_state = &lb_call_state_;
3902
- Metadata initial_metadata(
3903
- this,
3904
- seen_send_initial_metadata_
3905
- ? &send_initial_metadata_
3906
- : pending_batches_[0]
3907
- .batch->payload->send_initial_metadata.send_initial_metadata);
4055
+ Metadata initial_metadata(this, initial_metadata_batch);
3908
4056
  pick_args.initial_metadata = &initial_metadata;
3909
- // Grab initial metadata flags so that we can check later if the call has
3910
- // wait_for_ready enabled.
3911
- const uint32_t send_initial_metadata_flags =
3912
- seen_send_initial_metadata_ ? send_initial_metadata_flags_
3913
- : pending_batches_[0]
3914
- .batch->payload->send_initial_metadata
3915
- .send_initial_metadata_flags;
3916
4057
  // Attempt pick.
3917
4058
  auto result = chand->picker()->Pick(pick_args);
3918
4059
  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
@@ -3927,7 +4068,8 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
3927
4068
  grpc_error* disconnect_error = chand->disconnect_error();
3928
4069
  if (disconnect_error != GRPC_ERROR_NONE) {
3929
4070
  GRPC_ERROR_UNREF(result.error);
3930
- if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
4071
+ MaybeRemoveCallFromQueuedPicksLocked(elem);
4072
+ MaybeInvokeConfigSelectorCommitCallback();
3931
4073
  *error = GRPC_ERROR_REF(disconnect_error);
3932
4074
  return true;
3933
4075
  }
@@ -3948,8 +4090,9 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
3948
4090
  "Failed to pick subchannel", &result.error, 1);
3949
4091
  GRPC_ERROR_UNREF(result.error);
3950
4092
  *error = new_error;
4093
+ MaybeInvokeConfigSelectorCommitCallback();
3951
4094
  }
3952
- if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
4095
+ MaybeRemoveCallFromQueuedPicksLocked(elem);
3953
4096
  return !retried;
3954
4097
  }
3955
4098
  // If wait_for_ready is true, then queue to retry when we get a new
@@ -3958,22 +4101,24 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
3958
4101
  }
3959
4102
  // Fallthrough
3960
4103
  case LoadBalancingPolicy::PickResult::PICK_QUEUE:
3961
- if (!pick_queued_) AddCallToQueuedPicksLocked(elem);
4104
+ MaybeAddCallToQueuedPicksLocked(elem);
3962
4105
  return false;
3963
4106
  default: // PICK_COMPLETE
3964
- if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem);
4107
+ MaybeRemoveCallFromQueuedPicksLocked(elem);
3965
4108
  // Handle drops.
3966
4109
  if (GPR_UNLIKELY(result.subchannel == nullptr)) {
3967
4110
  result.error = grpc_error_set_int(
3968
4111
  GRPC_ERROR_CREATE_FROM_STATIC_STRING(
3969
4112
  "Call dropped by load balancing policy"),
3970
4113
  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
4114
+ MaybeInvokeConfigSelectorCommitCallback();
3971
4115
  } else {
3972
4116
  // Grab a ref to the connected subchannel while we're still
3973
4117
  // holding the data plane mutex.
3974
4118
  connected_subchannel_ =
3975
4119
  chand->GetConnectedSubchannelInDataPlane(result.subchannel.get());
3976
4120
  GPR_ASSERT(connected_subchannel_ != nullptr);
4121
+ if (retry_committed_) MaybeInvokeConfigSelectorCommitCallback();
3977
4122
  }
3978
4123
  lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready;
3979
4124
  *error = result.error;