grpc 1.19.0 → 1.20.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 (224) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +4131 -7903
  3. data/include/grpc/grpc.h +11 -6
  4. data/include/grpc/grpc_security.h +51 -9
  5. data/include/grpc/impl/codegen/byte_buffer.h +13 -0
  6. data/include/grpc/impl/codegen/grpc_types.h +4 -0
  7. data/include/grpc/impl/codegen/port_platform.h +37 -6
  8. data/include/grpc/impl/codegen/sync_posix.h +18 -0
  9. data/src/core/ext/filters/client_channel/client_channel.cc +560 -236
  10. data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -2
  11. data/src/core/ext/filters/client_channel/client_channel_factory.cc +22 -34
  12. data/src/core/ext/filters/client_channel/client_channel_factory.h +19 -38
  13. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +7 -4
  14. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +2 -2
  15. data/src/core/ext/filters/client_channel/lb_policy.cc +105 -28
  16. data/src/core/ext/filters/client_channel/lb_policy.h +259 -141
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +29 -32
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +789 -803
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +3 -1
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +2 -6
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +7 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +8 -8
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +2 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +127 -219
  26. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +103 -282
  27. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +4 -10
  28. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +709 -906
  29. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +0 -43
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +8 -8
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +2 -2
  32. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -6
  33. data/src/core/ext/filters/client_channel/resolver.cc +54 -1
  34. data/src/core/ext/filters/client_channel/resolver.h +51 -22
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +34 -86
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +29 -41
  37. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +32 -78
  38. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +109 -72
  39. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +13 -8
  40. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +28 -63
  41. data/src/core/ext/filters/client_channel/resolver_factory.h +3 -1
  42. data/src/core/ext/filters/client_channel/resolver_registry.cc +5 -2
  43. data/src/core/ext/filters/client_channel/resolver_registry.h +5 -4
  44. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +69 -49
  45. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +11 -8
  46. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +568 -0
  47. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +141 -0
  48. data/src/core/ext/filters/client_channel/server_address.cc +0 -48
  49. data/src/core/ext/filters/client_channel/server_address.h +0 -10
  50. data/src/core/{lib/transport → ext/filters/client_channel}/service_config.cc +10 -5
  51. data/src/core/{lib/transport → ext/filters/client_channel}/service_config.h +16 -12
  52. data/src/core/ext/filters/client_channel/subchannel.cc +11 -16
  53. data/src/core/ext/filters/client_channel/subchannel.h +3 -0
  54. data/src/core/ext/filters/max_age/max_age_filter.cc +4 -1
  55. data/src/core/ext/filters/message_size/message_size_filter.cc +2 -2
  56. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +45 -45
  57. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +133 -134
  58. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +4 -4
  59. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +4 -4
  60. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +7 -6
  61. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +4 -3
  62. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +37 -29
  63. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -1
  64. data/src/core/ext/transport/chttp2/transport/frame_data.cc +2 -1
  65. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  66. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +6 -5
  67. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +3 -2
  68. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -4
  69. data/src/core/ext/transport/chttp2/transport/frame_ping.h +1 -1
  70. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +5 -4
  71. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -1
  72. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +2 -1
  73. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -1
  74. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -4
  75. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +1 -1
  76. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +7 -6
  77. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -2
  78. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +9 -5
  79. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -1
  80. data/src/core/ext/transport/chttp2/transport/internal.h +5 -4
  81. data/src/core/ext/transport/chttp2/transport/parsing.cc +9 -9
  82. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -1
  83. data/src/core/ext/transport/inproc/inproc_transport.cc +8 -0
  84. data/src/core/lib/channel/channel_args.cc +2 -0
  85. data/src/core/lib/channel/channel_args.h +3 -0
  86. data/src/core/lib/channel/channel_stack.h +1 -1
  87. data/src/core/lib/channel/channel_trace.cc +4 -4
  88. data/src/core/lib/channel/channel_trace.h +4 -4
  89. data/src/core/lib/channel/channelz.cc +32 -19
  90. data/src/core/lib/channel/channelz.h +4 -4
  91. data/src/core/lib/channel/channelz_registry.cc +1 -1
  92. data/src/core/lib/channel/context.h +0 -3
  93. data/src/core/lib/channel/handshaker_registry.cc +7 -3
  94. data/src/core/lib/compression/algorithm_metadata.h +3 -3
  95. data/src/core/lib/compression/compression.cc +1 -1
  96. data/src/core/lib/compression/compression_internal.cc +2 -2
  97. data/src/core/lib/compression/stream_compression_gzip.cc +1 -1
  98. data/src/core/lib/debug/trace.h +2 -1
  99. data/src/core/lib/gpr/cpu_posix.cc +5 -3
  100. data/src/core/lib/gpr/sync_posix.cc +65 -4
  101. data/src/core/lib/gprpp/atomic.h +75 -5
  102. data/src/core/lib/gprpp/fork.cc +0 -2
  103. data/src/core/lib/gprpp/orphanable.h +3 -2
  104. data/src/core/lib/gprpp/ref_counted.h +9 -11
  105. data/src/core/lib/gprpp/thd.h +42 -7
  106. data/src/core/lib/gprpp/thd_posix.cc +31 -13
  107. data/src/core/lib/gprpp/thd_windows.cc +47 -34
  108. data/src/core/lib/http/httpcli.cc +3 -2
  109. data/src/core/lib/http/httpcli_security_connector.cc +0 -1
  110. data/src/core/lib/http/parser.cc +2 -1
  111. data/src/core/lib/http/parser.h +2 -1
  112. data/src/core/lib/iomgr/buffer_list.h +1 -1
  113. data/src/core/lib/iomgr/endpoint.cc +2 -2
  114. data/src/core/lib/iomgr/endpoint.h +3 -2
  115. data/src/core/lib/iomgr/error.cc +9 -9
  116. data/src/core/lib/iomgr/error.h +4 -3
  117. data/src/core/lib/iomgr/ev_epoll1_linux.cc +6 -0
  118. data/src/core/lib/iomgr/ev_epollex_linux.cc +14 -9
  119. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -481
  120. data/src/core/lib/iomgr/ev_posix.cc +7 -3
  121. data/src/core/lib/iomgr/ev_posix.h +8 -0
  122. data/src/core/lib/iomgr/executor.cc +13 -0
  123. data/src/core/lib/iomgr/executor.h +2 -1
  124. data/src/core/lib/iomgr/internal_errqueue.cc +2 -4
  125. data/src/core/lib/iomgr/iomgr.cc +5 -0
  126. data/src/core/lib/iomgr/iomgr.h +7 -0
  127. data/src/core/lib/iomgr/iomgr_custom.cc +9 -2
  128. data/src/core/lib/iomgr/iomgr_internal.cc +6 -0
  129. data/src/core/lib/iomgr/iomgr_internal.h +9 -1
  130. data/src/core/lib/iomgr/iomgr_posix.cc +10 -2
  131. data/src/core/lib/iomgr/iomgr_windows.cc +10 -2
  132. data/src/core/lib/iomgr/port.h +19 -0
  133. data/src/core/lib/iomgr/tcp_client_windows.cc +6 -4
  134. data/src/core/lib/iomgr/tcp_custom.cc +1 -1
  135. data/src/core/lib/iomgr/tcp_posix.cc +158 -54
  136. data/src/core/lib/iomgr/tcp_windows.cc +1 -1
  137. data/src/core/lib/iomgr/wakeup_fd_posix.cc +1 -19
  138. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +10 -6
  139. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  140. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +3 -6
  141. data/src/core/lib/security/credentials/tls/spiffe_credentials.cc +129 -0
  142. data/src/core/lib/security/credentials/tls/spiffe_credentials.h +62 -0
  143. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +7 -2
  144. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +28 -17
  145. data/src/core/lib/security/security_connector/ssl_utils.cc +134 -0
  146. data/src/core/lib/security/security_connector/ssl_utils.h +32 -0
  147. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +426 -0
  148. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +122 -0
  149. data/src/core/lib/security/transport/auth_filters.h +2 -2
  150. data/src/core/lib/security/transport/client_auth_filter.cc +35 -39
  151. data/src/core/lib/security/transport/secure_endpoint.cc +2 -2
  152. data/src/core/lib/security/transport/security_handshaker.cc +4 -3
  153. data/src/core/lib/slice/percent_encoding.cc +3 -3
  154. data/src/core/lib/slice/percent_encoding.h +3 -3
  155. data/src/core/lib/slice/slice.cc +27 -30
  156. data/src/core/lib/slice/slice_hash_table.h +2 -2
  157. data/src/core/lib/slice/slice_intern.cc +1 -1
  158. data/src/core/lib/slice/slice_internal.h +14 -3
  159. data/src/core/lib/slice/slice_weak_hash_table.h +4 -4
  160. data/src/core/lib/surface/byte_buffer_reader.cc +17 -0
  161. data/src/core/lib/surface/call.cc +8 -3
  162. data/src/core/lib/surface/completion_queue.cc +134 -148
  163. data/src/core/lib/surface/init.cc +78 -30
  164. data/src/core/lib/surface/init.h +1 -0
  165. data/src/core/lib/surface/lame_client.cc +4 -6
  166. data/src/core/lib/surface/version.cc +1 -1
  167. data/src/core/lib/transport/metadata.cc +66 -33
  168. data/src/core/lib/transport/metadata_batch.cc +1 -1
  169. data/src/core/lib/transport/metadata_batch.h +1 -1
  170. data/src/core/lib/transport/timeout_encoding.cc +1 -1
  171. data/src/core/lib/transport/timeout_encoding.h +1 -1
  172. data/src/core/lib/transport/transport.h +4 -3
  173. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
  174. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -1
  175. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +4 -3
  176. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
  177. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +1 -1
  178. data/src/core/tsi/ssl_transport_security.cc +1 -5
  179. data/src/core/tsi/ssl_transport_security.h +24 -4
  180. data/src/ruby/bin/math_pb.rb +18 -16
  181. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  182. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  183. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  184. data/src/ruby/lib/grpc/version.rb +1 -1
  185. data/src/ruby/pb/README.md +1 -1
  186. data/src/ruby/pb/grpc/health/v1/health_pb.rb +13 -10
  187. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +18 -0
  188. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +3 -1
  189. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +58 -56
  190. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -0
  191. data/third_party/cares/cares/ares.h +12 -0
  192. data/third_party/cares/cares/ares_create_query.c +5 -1
  193. data/third_party/cares/cares/ares_data.c +74 -73
  194. data/third_party/cares/cares/ares_destroy.c +6 -1
  195. data/third_party/cares/cares/ares_gethostbyaddr.c +5 -5
  196. data/third_party/cares/cares/ares_gethostbyname.c +15 -4
  197. data/third_party/cares/cares/ares_getnameinfo.c +11 -0
  198. data/third_party/cares/cares/ares_init.c +274 -173
  199. data/third_party/cares/cares/ares_library_init.c +21 -3
  200. data/third_party/cares/cares/ares_options.c +6 -2
  201. data/third_party/cares/cares/ares_parse_naptr_reply.c +7 -6
  202. data/third_party/cares/cares/ares_parse_ptr_reply.c +4 -2
  203. data/third_party/cares/cares/ares_platform.c +7 -0
  204. data/third_party/cares/cares/ares_private.h +19 -11
  205. data/third_party/cares/cares/ares_process.c +27 -2
  206. data/third_party/cares/cares/ares_rules.h +1 -1
  207. data/third_party/cares/cares/ares_search.c +7 -0
  208. data/third_party/cares/cares/ares_send.c +6 -0
  209. data/third_party/cares/cares/ares_strsplit.c +174 -0
  210. data/third_party/cares/cares/ares_strsplit.h +43 -0
  211. data/third_party/cares/cares/ares_version.h +4 -4
  212. data/third_party/cares/cares/config-win32.h +1 -1
  213. data/third_party/cares/cares/inet_ntop.c +2 -3
  214. data/third_party/cares/config_darwin/ares_config.h +3 -0
  215. data/third_party/cares/config_freebsd/ares_config.h +3 -0
  216. data/third_party/cares/config_linux/ares_config.h +3 -0
  217. data/third_party/cares/config_openbsd/ares_config.h +3 -0
  218. metadata +39 -37
  219. data/src/core/ext/filters/client_channel/request_routing.cc +0 -946
  220. data/src/core/ext/filters/client_channel/request_routing.h +0 -181
  221. data/src/core/lib/gprpp/atomic_with_atm.h +0 -57
  222. data/src/core/lib/gprpp/atomic_with_std.h +0 -35
  223. data/src/core/lib/iomgr/wakeup_fd_cv.cc +0 -107
  224. data/src/core/lib/iomgr/wakeup_fd_cv.h +0 -69
@@ -26,6 +26,7 @@
26
26
 
27
27
  #include <grpc/support/port_platform.h>
28
28
 
29
+ #include <stdlib.h>
29
30
  #include <string.h>
30
31
 
31
32
  #include <grpc/support/alloc.h>
@@ -60,19 +61,7 @@ class RoundRobin : public LoadBalancingPolicy {
60
61
 
61
62
  const char* name() const override { return kRoundRobin; }
62
63
 
63
- void UpdateLocked(const grpc_channel_args& args,
64
- grpc_json* lb_config) override;
65
- bool PickLocked(PickState* pick, grpc_error** error) override;
66
- void CancelPickLocked(PickState* pick, grpc_error* error) override;
67
- void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
68
- uint32_t initial_metadata_flags_eq,
69
- grpc_error* error) override;
70
- void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
71
- grpc_closure* closure) override;
72
- grpc_connectivity_state CheckConnectivityLocked(
73
- grpc_error** connectivity_error) override;
74
- void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
75
- void ExitIdleLocked() override;
64
+ void UpdateLocked(UpdateArgs args) override;
76
65
  void ResetBackoffLocked() override;
77
66
  void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
78
67
  channelz::ChildRefsList* ignored) override;
@@ -117,14 +106,12 @@ class RoundRobin : public LoadBalancingPolicy {
117
106
  : public SubchannelList<RoundRobinSubchannelList,
118
107
  RoundRobinSubchannelData> {
119
108
  public:
120
- RoundRobinSubchannelList(
121
- RoundRobin* policy, TraceFlag* tracer,
122
- const ServerAddressList& addresses, grpc_combiner* combiner,
123
- grpc_client_channel_factory* client_channel_factory,
124
- const grpc_channel_args& args)
109
+ RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer,
110
+ const ServerAddressList& addresses,
111
+ grpc_combiner* combiner,
112
+ const grpc_channel_args& args)
125
113
  : SubchannelList(policy, tracer, addresses, combiner,
126
- client_channel_factory, args),
127
- last_ready_index_(num_subchannels() - 1) {
114
+ policy->channel_control_helper(), args) {
128
115
  // Need to maintain a ref to the LB policy as long as we maintain
129
116
  // any references to subchannels, since the subchannels'
130
117
  // pollset_sets will include the LB policy's pollset_set.
@@ -157,15 +144,25 @@ class RoundRobin : public LoadBalancingPolicy {
157
144
  // subchannels in each state.
158
145
  void UpdateRoundRobinStateFromSubchannelStateCountsLocked();
159
146
 
160
- size_t GetNextReadySubchannelIndexLocked();
161
- void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
162
-
163
147
  private:
164
148
  size_t num_ready_ = 0;
165
149
  size_t num_connecting_ = 0;
166
150
  size_t num_transient_failure_ = 0;
167
151
  grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
168
- size_t last_ready_index_; // Index into list of last pick.
152
+ };
153
+
154
+ class Picker : public SubchannelPicker {
155
+ public:
156
+ Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list);
157
+
158
+ PickResult Pick(PickArgs* pick, grpc_error** error) override;
159
+
160
+ private:
161
+ // Using pointer value only, no ref held -- do not dereference!
162
+ RoundRobin* parent_;
163
+
164
+ size_t last_picked_index_;
165
+ InlinedVector<RefCountedPtr<ConnectedSubchannel>, 10> subchannels_;
169
166
  };
170
167
 
171
168
  // Helper class to ensure that any function that modifies the child refs
@@ -182,9 +179,6 @@ class RoundRobin : public LoadBalancingPolicy {
182
179
 
183
180
  void ShutdownLocked() override;
184
181
 
185
- void StartPickingLocked();
186
- bool DoPickLocked(PickState* pick);
187
- void DrainPendingPicksLocked();
188
182
  void UpdateChildRefsLocked();
189
183
 
190
184
  /** list of subchannels */
@@ -195,14 +189,8 @@ class RoundRobin : public LoadBalancingPolicy {
195
189
  * racing callbacks that reference outdated subchannel lists won't perform any
196
190
  * update. */
197
191
  OrphanablePtr<RoundRobinSubchannelList> latest_pending_subchannel_list_;
198
- /** have we started picking? */
199
- bool started_picking_ = false;
200
192
  /** are we shutting down? */
201
193
  bool shutdown_ = false;
202
- /** List of picks that are waiting on connectivity */
203
- PickState* pending_picks_ = nullptr;
204
- /** our connectivity state tracker */
205
- grpc_connectivity_state_tracker state_tracker_;
206
194
  /// Lock and data used to capture snapshots of this channel's child
207
195
  /// channels and subchannels. This data is consumed by channelz.
208
196
  gpr_mu child_refs_mu_;
@@ -210,15 +198,56 @@ class RoundRobin : public LoadBalancingPolicy {
210
198
  channelz::ChildRefsList child_channels_;
211
199
  };
212
200
 
201
+ //
202
+ // RoundRobin::Picker
203
+ //
204
+
205
+ RoundRobin::Picker::Picker(RoundRobin* parent,
206
+ RoundRobinSubchannelList* subchannel_list)
207
+ : parent_(parent) {
208
+ for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
209
+ auto* connected_subchannel =
210
+ subchannel_list->subchannel(i)->connected_subchannel();
211
+ if (connected_subchannel != nullptr) {
212
+ subchannels_.push_back(connected_subchannel->Ref());
213
+ }
214
+ }
215
+ // For discussion on why we generate a random starting index for
216
+ // the picker, see https://github.com/grpc/grpc-go/issues/2580.
217
+ // TODO(roth): rand(3) is not thread-safe. This should be replaced with
218
+ // something better as part of https://github.com/grpc/grpc/issues/17891.
219
+ last_picked_index_ = rand() % subchannels_.size();
220
+ if (grpc_lb_round_robin_trace.enabled()) {
221
+ gpr_log(GPR_INFO,
222
+ "[RR %p picker %p] created picker from subchannel_list=%p "
223
+ "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR,
224
+ parent_, this, subchannel_list, subchannels_.size(),
225
+ last_picked_index_);
226
+ }
227
+ }
228
+
229
+ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick,
230
+ grpc_error** error) {
231
+ last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size();
232
+ if (grpc_lb_round_robin_trace.enabled()) {
233
+ gpr_log(GPR_INFO,
234
+ "[RR %p picker %p] returning index %" PRIuPTR
235
+ ", connected_subchannel=%p",
236
+ parent_, this, last_picked_index_,
237
+ subchannels_[last_picked_index_].get());
238
+ }
239
+ pick->connected_subchannel = subchannels_[last_picked_index_];
240
+ return PICK_COMPLETE;
241
+ }
242
+
243
+ //
244
+ // RoundRobin
245
+ //
246
+
213
247
  RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) {
214
- GPR_ASSERT(args.client_channel_factory != nullptr);
215
248
  gpr_mu_init(&child_refs_mu_);
216
- grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
217
- "round_robin");
218
- UpdateLocked(*args.args, args.lb_config);
219
249
  if (grpc_lb_round_robin_trace.enabled()) {
220
- gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this,
221
- subchannel_list_->num_subchannels());
250
+ gpr_log(GPR_INFO, "[RR %p] Created", this);
222
251
  }
223
252
  }
224
253
 
@@ -229,93 +258,16 @@ RoundRobin::~RoundRobin() {
229
258
  gpr_mu_destroy(&child_refs_mu_);
230
259
  GPR_ASSERT(subchannel_list_ == nullptr);
231
260
  GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
232
- GPR_ASSERT(pending_picks_ == nullptr);
233
- grpc_connectivity_state_destroy(&state_tracker_);
234
- }
235
-
236
- void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
237
- PickState* pick;
238
- while ((pick = pending_picks_) != nullptr) {
239
- pending_picks_ = pick->next;
240
- grpc_error* error = GRPC_ERROR_NONE;
241
- if (new_policy->PickLocked(pick, &error)) {
242
- // Synchronous return, schedule closure.
243
- GRPC_CLOSURE_SCHED(pick->on_complete, error);
244
- }
245
- }
246
261
  }
247
262
 
248
263
  void RoundRobin::ShutdownLocked() {
249
264
  AutoChildRefsUpdater guard(this);
250
- grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
251
265
  if (grpc_lb_round_robin_trace.enabled()) {
252
266
  gpr_log(GPR_INFO, "[RR %p] Shutting down", this);
253
267
  }
254
268
  shutdown_ = true;
255
- PickState* pick;
256
- while ((pick = pending_picks_) != nullptr) {
257
- pending_picks_ = pick->next;
258
- pick->connected_subchannel.reset();
259
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
260
- }
261
- grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
262
- GRPC_ERROR_REF(error), "rr_shutdown");
263
269
  subchannel_list_.reset();
264
270
  latest_pending_subchannel_list_.reset();
265
- TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED);
266
- GRPC_ERROR_UNREF(error);
267
- }
268
-
269
- void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) {
270
- PickState* pp = pending_picks_;
271
- pending_picks_ = nullptr;
272
- while (pp != nullptr) {
273
- PickState* next = pp->next;
274
- if (pp == pick) {
275
- pick->connected_subchannel.reset();
276
- GRPC_CLOSURE_SCHED(pick->on_complete,
277
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
278
- "Pick Cancelled", &error, 1));
279
- } else {
280
- pp->next = pending_picks_;
281
- pending_picks_ = pp;
282
- }
283
- pp = next;
284
- }
285
- GRPC_ERROR_UNREF(error);
286
- }
287
-
288
- void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
289
- uint32_t initial_metadata_flags_eq,
290
- grpc_error* error) {
291
- PickState* pick = pending_picks_;
292
- pending_picks_ = nullptr;
293
- while (pick != nullptr) {
294
- PickState* next = pick->next;
295
- if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) ==
296
- initial_metadata_flags_eq) {
297
- pick->connected_subchannel.reset();
298
- GRPC_CLOSURE_SCHED(pick->on_complete,
299
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
300
- "Pick Cancelled", &error, 1));
301
- } else {
302
- pick->next = pending_picks_;
303
- pending_picks_ = pick;
304
- }
305
- pick = next;
306
- }
307
- GRPC_ERROR_UNREF(error);
308
- }
309
-
310
- void RoundRobin::StartPickingLocked() {
311
- started_picking_ = true;
312
- subchannel_list_->StartWatchingLocked();
313
- }
314
-
315
- void RoundRobin::ExitIdleLocked() {
316
- if (!started_picking_) {
317
- StartPickingLocked();
318
- }
319
271
  }
320
272
 
321
273
  void RoundRobin::ResetBackoffLocked() {
@@ -325,60 +277,6 @@ void RoundRobin::ResetBackoffLocked() {
325
277
  }
326
278
  }
327
279
 
328
- bool RoundRobin::DoPickLocked(PickState* pick) {
329
- const size_t next_ready_index =
330
- subchannel_list_->GetNextReadySubchannelIndexLocked();
331
- if (next_ready_index < subchannel_list_->num_subchannels()) {
332
- /* readily available, report right away */
333
- RoundRobinSubchannelData* sd =
334
- subchannel_list_->subchannel(next_ready_index);
335
- GPR_ASSERT(sd->connected_subchannel() != nullptr);
336
- pick->connected_subchannel = sd->connected_subchannel()->Ref();
337
- if (grpc_lb_round_robin_trace.enabled()) {
338
- gpr_log(GPR_INFO,
339
- "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
340
- "index %" PRIuPTR ")",
341
- this, sd->subchannel(), pick->connected_subchannel.get(),
342
- sd->subchannel_list(), next_ready_index);
343
- }
344
- /* only advance the last picked pointer if the selection was used */
345
- subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index);
346
- return true;
347
- }
348
- return false;
349
- }
350
-
351
- void RoundRobin::DrainPendingPicksLocked() {
352
- PickState* pick;
353
- while ((pick = pending_picks_)) {
354
- pending_picks_ = pick->next;
355
- GPR_ASSERT(DoPickLocked(pick));
356
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
357
- }
358
- }
359
-
360
- bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) {
361
- if (grpc_lb_round_robin_trace.enabled()) {
362
- gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_);
363
- }
364
- GPR_ASSERT(!shutdown_);
365
- if (subchannel_list_ != nullptr) {
366
- if (DoPickLocked(pick)) return true;
367
- }
368
- if (pick->on_complete == nullptr) {
369
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
370
- "No pick result available but synchronous result required.");
371
- return true;
372
- }
373
- /* no pick currently available. Save for later in list of pending picks */
374
- pick->next = pending_picks_;
375
- pending_picks_ = pick;
376
- if (!started_picking_) {
377
- StartPickingLocked();
378
- }
379
- return false;
380
- }
381
-
382
280
  void RoundRobin::FillChildRefsForChannelz(
383
281
  channelz::ChildRefsList* child_subchannels_to_fill,
384
282
  channelz::ChildRefsList* ignored) {
@@ -426,14 +324,14 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
426
324
  subchannel(i)->UpdateConnectivityStateLocked(state, error);
427
325
  }
428
326
  }
429
- // Now set the LB policy's state based on the subchannels' states.
430
- UpdateRoundRobinStateFromSubchannelStateCountsLocked();
431
327
  // Start connectivity watch for each subchannel.
432
328
  for (size_t i = 0; i < num_subchannels(); i++) {
433
329
  if (subchannel(i)->subchannel() != nullptr) {
434
330
  subchannel(i)->StartConnectivityWatchLocked();
435
331
  }
436
332
  }
333
+ // Now set the LB policy's state based on the subchannels' states.
334
+ UpdateRoundRobinStateFromSubchannelStateCountsLocked();
437
335
  }
438
336
 
439
337
  void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
@@ -462,8 +360,8 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
462
360
  last_transient_failure_error_ = transient_failure_error;
463
361
  }
464
362
 
465
- // Sets the RR policy's connectivity state based on the current
466
- // subchannel list.
363
+ // Sets the RR policy's connectivity state and generates a new picker based
364
+ // on the current subchannel list.
467
365
  void RoundRobin::RoundRobinSubchannelList::
468
366
  MaybeUpdateRoundRobinConnectivityStateLocked() {
469
367
  RoundRobin* p = static_cast<RoundRobin*>(policy());
@@ -485,18 +383,21 @@ void RoundRobin::RoundRobinSubchannelList::
485
383
  */
486
384
  if (num_ready_ > 0) {
487
385
  /* 1) READY */
488
- grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
489
- GRPC_ERROR_NONE, "rr_ready");
386
+ p->channel_control_helper()->UpdateState(
387
+ GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
388
+ UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
490
389
  } else if (num_connecting_ > 0) {
491
390
  /* 2) CONNECTING */
492
- grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
493
- GRPC_ERROR_NONE, "rr_connecting");
391
+ p->channel_control_helper()->UpdateState(
392
+ GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
393
+ UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
494
394
  } else if (num_transient_failure_ == num_subchannels()) {
495
395
  /* 3) TRANSIENT_FAILURE */
496
- grpc_connectivity_state_set(&p->state_tracker_,
497
- GRPC_CHANNEL_TRANSIENT_FAILURE,
498
- GRPC_ERROR_REF(last_transient_failure_error_),
499
- "rr_exhausted_subchannels");
396
+ p->channel_control_helper()->UpdateState(
397
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
398
+ GRPC_ERROR_REF(last_transient_failure_error_),
399
+ UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(
400
+ GRPC_ERROR_REF(last_transient_failure_error_))));
500
401
  }
501
402
  }
502
403
 
@@ -525,8 +426,6 @@ void RoundRobin::RoundRobinSubchannelList::
525
426
  }
526
427
  p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
527
428
  }
528
- // Drain pending picks.
529
- p->DrainPendingPicksLocked();
530
429
  }
531
430
  // Update the RR policy's connectivity state if needed.
532
431
  MaybeUpdateRoundRobinConnectivityStateLocked();
@@ -566,101 +465,21 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
566
465
  "Requesting re-resolution",
567
466
  p, subchannel());
568
467
  }
569
- p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
468
+ p->channel_control_helper()->RequestReresolution();
570
469
  }
470
+ // Renew connectivity watch.
471
+ RenewConnectivityWatchLocked();
571
472
  // Update state counters.
572
473
  UpdateConnectivityStateLocked(connectivity_state, error);
573
474
  // Update overall state and renew notification.
574
475
  subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
575
- RenewConnectivityWatchLocked();
576
- }
577
-
578
- /** Returns the index into p->subchannel_list->subchannels of the next
579
- * subchannel in READY state, or p->subchannel_list->num_subchannels if no
580
- * subchannel is READY.
581
- *
582
- * Note that this function does *not* update p->last_ready_subchannel_index.
583
- * The caller must do that if it returns a pick. */
584
- size_t
585
- RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() {
586
- if (grpc_lb_round_robin_trace.enabled()) {
587
- gpr_log(GPR_INFO,
588
- "[RR %p] getting next ready subchannel (out of %" PRIuPTR
589
- "), last_ready_index=%" PRIuPTR,
590
- policy(), num_subchannels(), last_ready_index_);
591
- }
592
- for (size_t i = 0; i < num_subchannels(); ++i) {
593
- const size_t index = (i + last_ready_index_ + 1) % num_subchannels();
594
- if (grpc_lb_round_robin_trace.enabled()) {
595
- gpr_log(
596
- GPR_INFO,
597
- "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
598
- ": state=%s",
599
- policy(), subchannel(index)->subchannel(), this, index,
600
- grpc_connectivity_state_name(
601
- subchannel(index)->connectivity_state()));
602
- }
603
- if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) {
604
- if (grpc_lb_round_robin_trace.enabled()) {
605
- gpr_log(GPR_INFO,
606
- "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
607
- " of subchannel_list %p",
608
- policy(), subchannel(index)->subchannel(), index, this);
609
- }
610
- return index;
611
- }
612
- }
613
- if (grpc_lb_round_robin_trace.enabled()) {
614
- gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this);
615
- }
616
- return num_subchannels();
617
- }
618
-
619
- // Sets last_ready_index_ to last_ready_index.
620
- void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked(
621
- size_t last_ready_index) {
622
- GPR_ASSERT(last_ready_index < num_subchannels());
623
- last_ready_index_ = last_ready_index;
624
- if (grpc_lb_round_robin_trace.enabled()) {
625
- gpr_log(GPR_INFO,
626
- "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
627
- " (SC %p, CSC %p)",
628
- policy(), last_ready_index,
629
- subchannel(last_ready_index)->subchannel(),
630
- subchannel(last_ready_index)->connected_subchannel());
631
- }
632
- }
633
-
634
- grpc_connectivity_state RoundRobin::CheckConnectivityLocked(
635
- grpc_error** error) {
636
- return grpc_connectivity_state_get(&state_tracker_, error);
637
476
  }
638
477
 
639
- void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
640
- grpc_closure* notify) {
641
- grpc_connectivity_state_notify_on_state_change(&state_tracker_, current,
642
- notify);
643
- }
644
-
645
- void RoundRobin::UpdateLocked(const grpc_channel_args& args,
646
- grpc_json* lb_config) {
478
+ void RoundRobin::UpdateLocked(UpdateArgs args) {
647
479
  AutoChildRefsUpdater guard(this);
648
- const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
649
- if (addresses == nullptr) {
650
- gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
651
- // If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
652
- // Otherwise, keep using the current subchannel list (ignore this update).
653
- if (subchannel_list_ == nullptr) {
654
- grpc_connectivity_state_set(
655
- &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
656
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
657
- "rr_update_missing");
658
- }
659
- return;
660
- }
661
480
  if (grpc_lb_round_robin_trace.enabled()) {
662
481
  gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
663
- this, addresses->size());
482
+ this, args.addresses.size());
664
483
  }
665
484
  // Replace latest_pending_subchannel_list_.
666
485
  if (latest_pending_subchannel_list_ != nullptr) {
@@ -671,21 +490,23 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args,
671
490
  }
672
491
  }
673
492
  latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
674
- this, &grpc_lb_round_robin_trace, *addresses, combiner(),
675
- client_channel_factory(), args);
676
- // If we haven't started picking yet or the new list is empty,
677
- // immediately promote the new list to the current list.
678
- if (!started_picking_ ||
679
- latest_pending_subchannel_list_->num_subchannels() == 0) {
680
- if (latest_pending_subchannel_list_->num_subchannels() == 0) {
681
- grpc_connectivity_state_set(
682
- &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
683
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
684
- "rr_update_empty");
685
- }
493
+ this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args);
494
+ if (latest_pending_subchannel_list_->num_subchannels() == 0) {
495
+ // If the new list is empty, immediately promote the new list to the
496
+ // current list and transition to TRANSIENT_FAILURE.
497
+ grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
498
+ channel_control_helper()->UpdateState(
499
+ GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
500
+ UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
501
+ subchannel_list_ = std::move(latest_pending_subchannel_list_);
502
+ } else if (subchannel_list_ == nullptr) {
503
+ // If there is no current list, immediately promote the new list to
504
+ // the current list and start watching it.
686
505
  subchannel_list_ = std::move(latest_pending_subchannel_list_);
506
+ subchannel_list_->StartWatchingLocked();
687
507
  } else {
688
- // If we've started picking, start watching the new list.
508
+ // Start watching the pending list. It will get swapped into the
509
+ // current list when it reports READY.
689
510
  latest_pending_subchannel_list_->StartWatchingLocked();
690
511
  }
691
512
  }