grpc 1.20.0 → 1.21.0

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 (209) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +500 -29
  3. data/etc/roots.pem +146 -0
  4. data/include/grpc/grpc_security.h +1 -1
  5. data/include/grpc/impl/codegen/grpc_types.h +10 -7
  6. data/include/grpc/impl/codegen/port_platform.h +11 -1
  7. data/include/grpc/impl/codegen/slice.h +1 -21
  8. data/include/grpc/impl/codegen/status.h +2 -1
  9. data/include/grpc/slice.h +1 -1
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +19 -13
  11. data/src/core/ext/filters/client_channel/backup_poller.h +3 -0
  12. data/src/core/ext/filters/client_channel/channel_connectivity.cc +1 -1
  13. data/src/core/ext/filters/client_channel/client_channel.cc +2084 -1673
  14. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +2 -3
  15. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +4 -0
  16. data/src/core/ext/filters/client_channel/health/health_check_client.cc +54 -49
  17. data/src/core/ext/filters/client_channel/health/health_check_client.h +20 -9
  18. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -2
  19. data/src/core/ext/filters/client_channel/http_connect_handshaker.h +1 -1
  20. data/src/core/ext/filters/client_channel/lb_policy.cc +3 -30
  21. data/src/core/ext/filters/client_channel/lb_policy.h +16 -25
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +106 -81
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +6 -2
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +8 -12
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +2 -2
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +1 -1
  27. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +57 -49
  28. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +47 -41
  29. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +24 -20
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +989 -284
  31. data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -1
  32. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +105 -2
  33. data/src/core/ext/filters/client_channel/lb_policy_registry.h +9 -2
  34. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +79 -36
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +84 -2
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +3 -0
  37. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +179 -0
  38. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +15 -3
  39. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +80 -4
  40. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +7 -13
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +2 -2
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +39 -0
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +0 -6
  44. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +2 -64
  45. data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc +28 -0
  46. data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h +29 -0
  47. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +4 -4
  48. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +367 -232
  49. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +55 -76
  50. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +50 -39
  51. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +18 -12
  52. data/src/core/ext/filters/client_channel/service_config.cc +247 -27
  53. data/src/core/ext/filters/client_channel/service_config.h +119 -166
  54. data/src/core/ext/filters/client_channel/subchannel.cc +46 -84
  55. data/src/core/ext/filters/client_channel/subchannel.h +7 -7
  56. data/src/core/ext/filters/deadline/deadline_filter.cc +3 -4
  57. data/src/core/ext/filters/deadline/deadline_filter.h +3 -2
  58. data/src/core/ext/filters/http/client/http_client_filter.cc +7 -5
  59. data/src/core/ext/filters/http/client/http_client_filter.h +1 -1
  60. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  61. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +4 -3
  62. data/src/core/ext/filters/http/server/http_server_filter.cc +18 -12
  63. data/src/core/ext/filters/message_size/message_size_filter.cc +118 -76
  64. data/src/core/ext/filters/message_size/message_size_filter.h +33 -0
  65. data/src/core/ext/transport/chttp2/alpn/alpn.h +1 -1
  66. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +9 -7
  67. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +93 -60
  68. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -1
  69. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +4 -3
  70. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +3 -3
  71. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +8 -2
  72. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +2 -2
  73. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +1 -1
  74. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +3 -2
  75. data/src/core/ext/transport/chttp2/transport/internal.h +35 -23
  76. data/src/core/ext/transport/chttp2/transport/parsing.cc +4 -4
  77. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +3 -3
  78. data/src/core/ext/transport/chttp2/transport/writing.cc +61 -27
  79. data/src/core/ext/transport/inproc/inproc_transport.cc +18 -18
  80. data/src/core/lib/channel/channel_args.cc +0 -101
  81. data/src/core/lib/channel/channel_args.h +0 -37
  82. data/src/core/lib/channel/channel_stack.h +9 -5
  83. data/src/core/lib/channel/channelz_registry.cc +1 -1
  84. data/src/core/lib/channel/connected_channel.cc +2 -2
  85. data/src/core/lib/channel/context.h +3 -0
  86. data/src/core/lib/channel/handshaker.cc +4 -4
  87. data/src/core/lib/channel/handshaker.h +1 -1
  88. data/src/core/lib/compression/compression_args.cc +127 -0
  89. data/src/core/lib/compression/compression_args.h +55 -0
  90. data/src/core/lib/debug/trace.cc +13 -7
  91. data/src/core/lib/debug/trace.h +12 -0
  92. data/src/core/lib/gpr/arena.h +13 -9
  93. data/src/core/lib/gpr/env.h +2 -5
  94. data/src/core/lib/gpr/env_linux.cc +6 -1
  95. data/src/core/lib/gpr/env_posix.cc +5 -0
  96. data/src/core/lib/gpr/env_windows.cc +7 -5
  97. data/src/core/lib/gpr/log.cc +9 -13
  98. data/src/core/lib/gpr/string.cc +12 -6
  99. data/src/core/lib/gpr/string.h +4 -2
  100. data/src/core/lib/gpr/time_posix.cc +13 -0
  101. data/src/core/lib/gprpp/arena.cc +103 -0
  102. data/src/core/lib/gprpp/arena.h +121 -0
  103. data/src/core/lib/gprpp/fork.cc +12 -29
  104. data/src/core/lib/gprpp/global_config.h +87 -0
  105. data/src/core/lib/gprpp/global_config_custom.h +29 -0
  106. data/src/core/lib/gprpp/global_config_env.cc +135 -0
  107. data/src/core/lib/gprpp/global_config_env.h +131 -0
  108. data/src/core/lib/gprpp/global_config_generic.h +44 -0
  109. data/src/core/lib/gprpp/map.h +419 -0
  110. data/src/core/lib/gprpp/optional.h +1 -0
  111. data/src/core/lib/gprpp/orphanable.h +2 -2
  112. data/src/core/lib/gprpp/{mutex_lock.h → pair.h} +15 -19
  113. data/src/core/lib/gprpp/ref_counted.h +18 -2
  114. data/src/core/lib/gprpp/sync.h +126 -0
  115. data/src/core/lib/http/parser.cc +1 -1
  116. data/src/core/lib/iomgr/call_combiner.cc +84 -90
  117. data/src/core/lib/iomgr/call_combiner.h +75 -82
  118. data/src/core/lib/iomgr/cfstream_handle.cc +202 -0
  119. data/src/core/lib/iomgr/cfstream_handle.h +82 -0
  120. data/src/core/lib/iomgr/combiner.h +1 -1
  121. data/src/core/lib/iomgr/endpoint_cfstream.cc +375 -0
  122. data/src/core/lib/iomgr/endpoint_cfstream.h +49 -0
  123. data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
  124. data/src/core/lib/iomgr/error.h +23 -0
  125. data/src/core/lib/iomgr/error_cfstream.cc +52 -0
  126. data/src/core/lib/iomgr/error_cfstream.h +31 -0
  127. data/src/core/lib/iomgr/ev_epoll1_linux.cc +34 -27
  128. data/src/core/lib/iomgr/ev_epollex_linux.cc +33 -33
  129. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -7
  130. data/src/core/lib/iomgr/ev_posix.cc +15 -13
  131. data/src/core/lib/iomgr/ev_posix.h +4 -1
  132. data/src/core/lib/iomgr/executor.cc +13 -9
  133. data/src/core/lib/iomgr/fork_posix.cc +0 -1
  134. data/src/core/lib/iomgr/internal_errqueue.cc +1 -1
  135. data/src/core/lib/iomgr/iomgr.cc +6 -5
  136. data/src/core/lib/iomgr/iomgr_custom.cc +3 -0
  137. data/src/core/lib/iomgr/iomgr_custom.h +2 -0
  138. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +93 -0
  139. data/src/core/lib/iomgr/iomgr_windows.cc +1 -0
  140. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  141. data/src/core/lib/iomgr/port.h +11 -0
  142. data/src/core/lib/iomgr/resource_quota.cc +40 -37
  143. data/src/core/lib/iomgr/socket_utils_common_posix.cc +6 -2
  144. data/src/core/lib/iomgr/socket_windows.cc +19 -0
  145. data/src/core/lib/iomgr/socket_windows.h +8 -0
  146. data/src/core/lib/iomgr/tcp_client_cfstream.cc +216 -0
  147. data/src/core/lib/iomgr/tcp_client_custom.cc +2 -2
  148. data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
  149. data/src/core/lib/iomgr/tcp_client_windows.cc +1 -1
  150. data/src/core/lib/iomgr/tcp_custom.cc +9 -9
  151. data/src/core/lib/iomgr/tcp_posix.cc +41 -41
  152. data/src/core/lib/iomgr/tcp_server_custom.cc +3 -3
  153. data/src/core/lib/iomgr/tcp_server_posix.cc +14 -1
  154. data/src/core/lib/iomgr/tcp_server_windows.cc +2 -2
  155. data/src/core/lib/iomgr/tcp_windows.cc +7 -9
  156. data/src/core/lib/iomgr/timer_generic.cc +16 -16
  157. data/src/core/lib/iomgr/timer_manager.cc +12 -11
  158. data/src/core/lib/profiling/basic_timers.cc +10 -4
  159. data/src/core/lib/security/context/security_context.cc +6 -7
  160. data/src/core/lib/security/context/security_context.h +3 -4
  161. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
  162. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -3
  163. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
  164. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +7 -7
  165. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +7 -5
  166. data/src/core/lib/security/security_connector/security_connector.cc +0 -1
  167. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +3 -2
  168. data/src/core/lib/security/security_connector/ssl_utils.cc +30 -26
  169. data/src/core/lib/security/security_connector/ssl_utils.h +5 -1
  170. data/src/core/lib/security/transport/client_auth_filter.cc +7 -11
  171. data/src/core/lib/security/transport/secure_endpoint.cc +4 -4
  172. data/src/core/lib/security/transport/server_auth_filter.cc +2 -3
  173. data/src/core/lib/slice/slice.cc +99 -116
  174. data/src/core/lib/slice/slice_buffer.cc +5 -0
  175. data/src/core/lib/slice/slice_intern.cc +38 -95
  176. data/src/core/lib/slice/slice_internal.h +200 -2
  177. data/src/core/lib/surface/api_trace.h +1 -1
  178. data/src/core/lib/surface/call.cc +41 -35
  179. data/src/core/lib/surface/call.h +7 -2
  180. data/src/core/lib/surface/call_details.cc +0 -1
  181. data/src/core/lib/surface/completion_queue.cc +36 -27
  182. data/src/core/lib/surface/init.cc +3 -4
  183. data/src/core/lib/surface/lame_client.cc +1 -1
  184. data/src/core/lib/surface/server.cc +18 -25
  185. data/src/core/lib/surface/version.cc +1 -1
  186. data/src/core/lib/transport/bdp_estimator.cc +3 -3
  187. data/src/core/lib/transport/bdp_estimator.h +2 -2
  188. data/src/core/lib/transport/connectivity_state.cc +10 -40
  189. data/src/core/lib/transport/connectivity_state.h +0 -8
  190. data/src/core/lib/transport/error_utils.cc +12 -0
  191. data/src/core/lib/transport/metadata.cc +206 -278
  192. data/src/core/lib/transport/metadata.h +205 -10
  193. data/src/core/lib/transport/static_metadata.cc +108 -116
  194. data/src/core/lib/transport/static_metadata.h +1 -2
  195. data/src/core/lib/transport/status_metadata.cc +3 -3
  196. data/src/core/lib/transport/transport.cc +29 -66
  197. data/src/core/lib/transport/transport.h +36 -8
  198. data/src/core/lib/transport/transport_impl.h +1 -1
  199. data/src/core/tsi/fake_transport_security.cc +4 -4
  200. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +1 -1
  201. data/src/core/tsi/ssl_transport_security.cc +1 -1
  202. data/src/ruby/ext/grpc/rb_grpc.c +1 -1
  203. data/src/ruby/lib/grpc/errors.rb +22 -3
  204. data/src/ruby/lib/grpc/generic/bidi_call.rb +1 -1
  205. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  206. data/src/ruby/lib/grpc/version.rb +1 -1
  207. data/src/ruby/spec/errors_spec.rb +141 -0
  208. metadata +57 -33
  209. data/src/core/lib/gpr/arena.cc +0 -192
@@ -25,6 +25,8 @@
25
25
  #include <grpc/support/atm.h>
26
26
  #include <grpc/support/string_util.h>
27
27
 
28
+ #include "src/core/lib/gprpp/sync.h"
29
+
28
30
  namespace grpc_core {
29
31
 
30
32
  void GrpcLbClientStats::AddCallStarted() {
@@ -43,11 +45,12 @@ void GrpcLbClientStats::AddCallFinished(
43
45
  }
44
46
  }
45
47
 
46
- void GrpcLbClientStats::AddCallDroppedLocked(const char* token) {
48
+ void GrpcLbClientStats::AddCallDropped(const char* token) {
47
49
  // Increment num_calls_started and num_calls_finished.
48
50
  gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
49
51
  gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
50
52
  // Record the drop.
53
+ MutexLock lock(&drop_count_mu_);
51
54
  if (drop_token_counts_ == nullptr) {
52
55
  drop_token_counts_.reset(New<DroppedCallCounts>());
53
56
  }
@@ -69,7 +72,7 @@ void AtomicGetAndResetCounter(int64_t* value, gpr_atm* counter) {
69
72
 
70
73
  } // namespace
71
74
 
72
- void GrpcLbClientStats::GetLocked(
75
+ void GrpcLbClientStats::Get(
73
76
  int64_t* num_calls_started, int64_t* num_calls_finished,
74
77
  int64_t* num_calls_finished_with_client_failed_to_send,
75
78
  int64_t* num_calls_finished_known_received,
@@ -80,6 +83,7 @@ void GrpcLbClientStats::GetLocked(
80
83
  &num_calls_finished_with_client_failed_to_send_);
81
84
  AtomicGetAndResetCounter(num_calls_finished_known_received,
82
85
  &num_calls_finished_known_received_);
86
+ MutexLock lock(&drop_count_mu_);
83
87
  *drop_token_counts = std::move(drop_token_counts_);
84
88
  }
85
89
 
@@ -26,6 +26,7 @@
26
26
  #include "src/core/lib/gprpp/inlined_vector.h"
27
27
  #include "src/core/lib/gprpp/memory.h"
28
28
  #include "src/core/lib/gprpp/ref_counted.h"
29
+ #include "src/core/lib/gprpp/sync.h"
29
30
 
30
31
  namespace grpc_core {
31
32
 
@@ -41,20 +42,16 @@ class GrpcLbClientStats : public RefCounted<GrpcLbClientStats> {
41
42
 
42
43
  typedef InlinedVector<DropTokenCount, 10> DroppedCallCounts;
43
44
 
44
- GrpcLbClientStats() {}
45
-
46
45
  void AddCallStarted();
47
46
  void AddCallFinished(bool finished_with_client_failed_to_send,
48
47
  bool finished_known_received);
49
48
 
50
- // This method is not thread-safe; caller must synchronize.
51
- void AddCallDroppedLocked(const char* token);
49
+ void AddCallDropped(const char* token);
52
50
 
53
- // This method is not thread-safe; caller must synchronize.
54
- void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished,
55
- int64_t* num_calls_finished_with_client_failed_to_send,
56
- int64_t* num_calls_finished_known_received,
57
- UniquePtr<DroppedCallCounts>* drop_token_counts);
51
+ void Get(int64_t* num_calls_started, int64_t* num_calls_finished,
52
+ int64_t* num_calls_finished_with_client_failed_to_send,
53
+ int64_t* num_calls_finished_known_received,
54
+ UniquePtr<DroppedCallCounts>* drop_token_counts);
58
55
 
59
56
  // A destruction function to use as the user_data key when attaching
60
57
  // client stats to a grpc_mdelem.
@@ -63,13 +60,12 @@ class GrpcLbClientStats : public RefCounted<GrpcLbClientStats> {
63
60
  }
64
61
 
65
62
  private:
66
- // This field must only be accessed via *_locked() methods.
67
- UniquePtr<DroppedCallCounts> drop_token_counts_;
68
- // These fields may be accessed from multiple threads at a time.
69
63
  gpr_atm num_calls_started_ = 0;
70
64
  gpr_atm num_calls_finished_ = 0;
71
65
  gpr_atm num_calls_finished_with_client_failed_to_send_ = 0;
72
66
  gpr_atm num_calls_finished_known_received_ = 0;
67
+ Mutex drop_count_mu_; // Guards drop_token_counts_.
68
+ UniquePtr<DroppedCallCounts> drop_token_counts_;
73
69
  };
74
70
 
75
71
  } // namespace grpc_core
@@ -107,7 +107,7 @@ static bool encode_drops(pb_ostream_t* stream, const pb_field_t* field,
107
107
  return true;
108
108
  }
109
109
 
110
- grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
110
+ grpc_grpclb_request* grpc_grpclb_load_report_request_create(
111
111
  grpc_core::GrpcLbClientStats* client_stats) {
112
112
  grpc_grpclb_request* req = static_cast<grpc_grpclb_request*>(
113
113
  gpr_zalloc(sizeof(grpc_grpclb_request)));
@@ -122,7 +122,7 @@ grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
122
122
  req->client_stats.calls_finished_with_drop.funcs.encode = encode_drops;
123
123
  grpc_core::UniquePtr<grpc_core::GrpcLbClientStats::DroppedCallCounts>
124
124
  drop_counts;
125
- client_stats->GetLocked(
125
+ client_stats->Get(
126
126
  &req->client_stats.num_calls_started,
127
127
  &req->client_stats.num_calls_finished,
128
128
  &req->client_stats.num_calls_finished_with_client_failed_to_send,
@@ -43,7 +43,7 @@ typedef struct {
43
43
 
44
44
  /** Create a request for a gRPC LB service under \a lb_service_name */
45
45
  grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name);
46
- grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
46
+ grpc_grpclb_request* grpc_grpclb_load_report_request_create(
47
47
  grpc_core::GrpcLbClientStats* client_stats);
48
48
 
49
49
  /** Protocol Buffers v3-encode \a request */
@@ -27,7 +27,7 @@
27
27
  #include "src/core/ext/filters/client_channel/server_address.h"
28
28
  #include "src/core/ext/filters/client_channel/subchannel.h"
29
29
  #include "src/core/lib/channel/channel_args.h"
30
- #include "src/core/lib/gprpp/mutex_lock.h"
30
+ #include "src/core/lib/gprpp/sync.h"
31
31
  #include "src/core/lib/iomgr/combiner.h"
32
32
  #include "src/core/lib/iomgr/sockaddr_utils.h"
33
33
  #include "src/core/lib/transport/connectivity_state.h"
@@ -73,7 +73,7 @@ class PickFirst : public LoadBalancingPolicy {
73
73
  : SubchannelData(subchannel_list, address, subchannel, combiner) {}
74
74
 
75
75
  void ProcessConnectivityChangeLocked(
76
- grpc_connectivity_state connectivity_state, grpc_error* error) override;
76
+ grpc_connectivity_state connectivity_state) override;
77
77
 
78
78
  // Processes the connectivity change to READY for an unselected subchannel.
79
79
  void ProcessUnselectedReadyLocked();
@@ -154,30 +154,28 @@ class PickFirst : public LoadBalancingPolicy {
154
154
 
155
155
  /// Lock and data used to capture snapshots of this channels child
156
156
  /// channels and subchannels. This data is consumed by channelz.
157
- gpr_mu child_refs_mu_;
157
+ Mutex child_refs_mu_;
158
158
  channelz::ChildRefsList child_subchannels_;
159
159
  channelz::ChildRefsList child_channels_;
160
160
  };
161
161
 
162
162
  PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) {
163
- gpr_mu_init(&child_refs_mu_);
164
- if (grpc_lb_pick_first_trace.enabled()) {
163
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
165
164
  gpr_log(GPR_INFO, "Pick First %p created.", this);
166
165
  }
167
166
  }
168
167
 
169
168
  PickFirst::~PickFirst() {
170
- if (grpc_lb_pick_first_trace.enabled()) {
169
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
171
170
  gpr_log(GPR_INFO, "Destroying Pick First %p", this);
172
171
  }
173
- gpr_mu_destroy(&child_refs_mu_);
174
172
  GPR_ASSERT(subchannel_list_ == nullptr);
175
173
  GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
176
174
  }
177
175
 
178
176
  void PickFirst::ShutdownLocked() {
179
177
  AutoChildRefsUpdater guard(this);
180
- if (grpc_lb_pick_first_trace.enabled()) {
178
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
181
179
  gpr_log(GPR_INFO, "Pick First %p Shutting down", this);
182
180
  }
183
181
  shutdown_ = true;
@@ -186,14 +184,16 @@ void PickFirst::ShutdownLocked() {
186
184
  }
187
185
 
188
186
  void PickFirst::ExitIdleLocked() {
187
+ if (shutdown_) return;
189
188
  if (idle_) {
190
189
  idle_ = false;
191
190
  if (subchannel_list_ == nullptr ||
192
191
  subchannel_list_->num_subchannels() == 0) {
193
- grpc_error* error =
194
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to");
192
+ grpc_error* error = grpc_error_set_int(
193
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"),
194
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
195
195
  channel_control_helper()->UpdateState(
196
- GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
196
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
197
197
  UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
198
198
  } else {
199
199
  subchannel_list_->subchannel(0)
@@ -245,7 +245,7 @@ void PickFirst::UpdateChildRefsLocked() {
245
245
 
246
246
  void PickFirst::UpdateLocked(UpdateArgs args) {
247
247
  AutoChildRefsUpdater guard(this);
248
- if (grpc_lb_pick_first_trace.enabled()) {
248
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
249
249
  gpr_log(GPR_INFO,
250
250
  "Pick First %p received update with %" PRIuPTR " addresses", this,
251
251
  args.addresses.size());
@@ -267,9 +267,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
267
267
  // haven't gotten a non-empty update by the time the application tries
268
268
  // to start a new call.)
269
269
  if (!idle_) {
270
- grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
270
+ grpc_error* error = grpc_error_set_int(
271
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
272
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
271
273
  channel_control_helper()->UpdateState(
272
- GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
274
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
273
275
  UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
274
276
  }
275
277
  return;
@@ -283,9 +285,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
283
285
  // check and instead do it in ExitIdleLocked().
284
286
  for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
285
287
  PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
286
- grpc_error* error = GRPC_ERROR_NONE;
287
- grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error);
288
- GRPC_ERROR_UNREF(error);
288
+ grpc_connectivity_state state = sd->CheckConnectivityStateLocked();
289
289
  if (state == GRPC_CHANNEL_READY) {
290
290
  subchannel_list_ = std::move(subchannel_list);
291
291
  sd->StartConnectivityWatchLocked();
@@ -317,7 +317,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
317
317
  // We do have a selected subchannel (which means it's READY), so keep
318
318
  // using it until one of the subchannels in the new list reports READY.
319
319
  if (latest_pending_subchannel_list_ != nullptr) {
320
- if (grpc_lb_pick_first_trace.enabled()) {
320
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
321
321
  gpr_log(GPR_INFO,
322
322
  "Pick First %p Shutting down latest pending subchannel list "
323
323
  "%p, about to be replaced by newer latest %p",
@@ -339,7 +339,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) {
339
339
  }
340
340
 
341
341
  void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
342
- grpc_connectivity_state connectivity_state, grpc_error* error) {
342
+ grpc_connectivity_state connectivity_state) {
343
343
  PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
344
344
  AutoChildRefsUpdater guard(p);
345
345
  // The notification must be for a subchannel in either the current or
@@ -349,7 +349,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
349
349
  GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN);
350
350
  // Handle updates for the currently selected subchannel.
351
351
  if (p->selected_ == this) {
352
- if (grpc_lb_pick_first_trace.enabled()) {
352
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
353
353
  gpr_log(GPR_INFO,
354
354
  "Pick First %p selected subchannel connectivity changed to %s", p,
355
355
  grpc_connectivity_state_name(connectivity_state));
@@ -358,7 +358,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
358
358
  // pending update, switch to the pending update.
359
359
  if (connectivity_state != GRPC_CHANNEL_READY &&
360
360
  p->latest_pending_subchannel_list_ != nullptr) {
361
- if (grpc_lb_pick_first_trace.enabled()) {
361
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
362
362
  gpr_log(GPR_INFO,
363
363
  "Pick First %p promoting pending subchannel list %p to "
364
364
  "replace %p",
@@ -370,17 +370,16 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
370
370
  p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
371
371
  // Set our state to that of the pending subchannel list.
372
372
  if (p->subchannel_list_->in_transient_failure()) {
373
- grpc_error* new_error =
374
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
375
- "selected subchannel failed; switching to pending update",
376
- &error, 1);
373
+ grpc_error* error = grpc_error_set_int(
374
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING(
375
+ "selected subchannel failed; switching to pending update"),
376
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
377
377
  p->channel_control_helper()->UpdateState(
378
- GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
379
- UniquePtr<SubchannelPicker>(
380
- New<TransientFailurePicker>(new_error)));
378
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
379
+ UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
381
380
  } else {
382
381
  p->channel_control_helper()->UpdateState(
383
- GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
382
+ GRPC_CHANNEL_CONNECTING,
384
383
  UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
385
384
  }
386
385
  } else {
@@ -394,7 +393,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
394
393
  p->selected_ = nullptr;
395
394
  StopConnectivityWatchLocked();
396
395
  p->channel_control_helper()->UpdateState(
397
- GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
396
+ GRPC_CHANNEL_IDLE,
398
397
  UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
399
398
  } else {
400
399
  // This is unlikely but can happen when a subchannel has been asked
@@ -402,19 +401,17 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
402
401
  // some connectivity state notifications.
403
402
  if (connectivity_state == GRPC_CHANNEL_READY) {
404
403
  p->channel_control_helper()->UpdateState(
405
- GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
406
- UniquePtr<SubchannelPicker>(
407
- New<Picker>(connected_subchannel()->Ref())));
404
+ GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(
405
+ connected_subchannel()->Ref())));
408
406
  } else { // CONNECTING
409
407
  p->channel_control_helper()->UpdateState(
410
- connectivity_state, GRPC_ERROR_REF(error),
408
+ connectivity_state,
411
409
  UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
412
410
  }
413
411
  // Renew notification.
414
412
  RenewConnectivityWatchLocked();
415
413
  }
416
414
  }
417
- GRPC_ERROR_UNREF(error);
418
415
  return;
419
416
  }
420
417
  // If we get here, there are two possible cases:
@@ -451,13 +448,13 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
451
448
  subchannel_list()->set_in_transient_failure(true);
452
449
  // Only report new state in case 1.
453
450
  if (subchannel_list() == p->subchannel_list_.get()) {
454
- grpc_error* new_error =
455
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
456
- "failed to connect to all addresses", &error, 1);
451
+ grpc_error* error = grpc_error_set_int(
452
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING(
453
+ "failed to connect to all addresses"),
454
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
457
455
  p->channel_control_helper()->UpdateState(
458
- GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error),
459
- UniquePtr<SubchannelPicker>(
460
- New<TransientFailurePicker>(new_error)));
456
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
457
+ UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
461
458
  }
462
459
  }
463
460
  sd->CheckConnectivityStateAndStartWatchingLocked();
@@ -468,7 +465,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
468
465
  // Only update connectivity state in case 1.
469
466
  if (subchannel_list() == p->subchannel_list_.get()) {
470
467
  p->channel_control_helper()->UpdateState(
471
- GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
468
+ GRPC_CHANNEL_CONNECTING,
472
469
  UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
473
470
  }
474
471
  // Renew notification.
@@ -478,7 +475,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
478
475
  case GRPC_CHANNEL_SHUTDOWN:
479
476
  GPR_UNREACHABLE_CODE(break);
480
477
  }
481
- GRPC_ERROR_UNREF(error);
482
478
  }
483
479
 
484
480
  void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
@@ -496,7 +492,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
496
492
  subchannel_list() == p->latest_pending_subchannel_list_.get());
497
493
  // Case 2. Promote p->latest_pending_subchannel_list_ to p->subchannel_list_.
498
494
  if (subchannel_list() == p->latest_pending_subchannel_list_.get()) {
499
- if (grpc_lb_pick_first_trace.enabled()) {
495
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
500
496
  gpr_log(GPR_INFO,
501
497
  "Pick First %p promoting pending subchannel list %p to "
502
498
  "replace %p",
@@ -508,9 +504,9 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
508
504
  // Cases 1 and 2.
509
505
  p->selected_ = this;
510
506
  p->channel_control_helper()->UpdateState(
511
- GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
507
+ GRPC_CHANNEL_READY,
512
508
  UniquePtr<SubchannelPicker>(New<Picker>(connected_subchannel()->Ref())));
513
- if (grpc_lb_pick_first_trace.enabled()) {
509
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) {
514
510
  gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
515
511
  }
516
512
  }
@@ -519,9 +515,7 @@ void PickFirst::PickFirstSubchannelData::
519
515
  CheckConnectivityStateAndStartWatchingLocked() {
520
516
  PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
521
517
  // Check current state.
522
- grpc_error* error = GRPC_ERROR_NONE;
523
- grpc_connectivity_state current_state = CheckConnectivityStateLocked(&error);
524
- GRPC_ERROR_UNREF(error);
518
+ grpc_connectivity_state current_state = CheckConnectivityStateLocked();
525
519
  // Start watch.
526
520
  StartConnectivityWatchLocked();
527
521
  // If current state is READY, select the subchannel now, since we started
@@ -532,6 +526,11 @@ void PickFirst::PickFirstSubchannelData::
532
526
  }
533
527
  }
534
528
 
529
+ class ParsedPickFirstConfig : public ParsedLoadBalancingConfig {
530
+ public:
531
+ const char* name() const override { return kPickFirst; }
532
+ };
533
+
535
534
  //
536
535
  // factory
537
536
  //
@@ -544,6 +543,15 @@ class PickFirstFactory : public LoadBalancingPolicyFactory {
544
543
  }
545
544
 
546
545
  const char* name() const override { return kPickFirst; }
546
+
547
+ RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
548
+ const grpc_json* json, grpc_error** error) const override {
549
+ if (json != nullptr) {
550
+ GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0);
551
+ }
552
+ return RefCountedPtr<ParsedLoadBalancingConfig>(
553
+ New<ParsedPickFirstConfig>());
554
+ }
547
555
  };
548
556
 
549
557
  } // namespace
@@ -36,8 +36,8 @@
36
36
  #include "src/core/ext/filters/client_channel/subchannel.h"
37
37
  #include "src/core/lib/channel/channel_args.h"
38
38
  #include "src/core/lib/debug/trace.h"
39
- #include "src/core/lib/gprpp/mutex_lock.h"
40
39
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
40
+ #include "src/core/lib/gprpp/sync.h"
41
41
  #include "src/core/lib/iomgr/combiner.h"
42
42
  #include "src/core/lib/iomgr/sockaddr_utils.h"
43
43
  #include "src/core/lib/transport/connectivity_state.h"
@@ -92,11 +92,11 @@ class RoundRobin : public LoadBalancingPolicy {
92
92
  }
93
93
 
94
94
  void UpdateConnectivityStateLocked(
95
- grpc_connectivity_state connectivity_state, grpc_error* error);
95
+ grpc_connectivity_state connectivity_state);
96
96
 
97
97
  private:
98
98
  void ProcessConnectivityChangeLocked(
99
- grpc_connectivity_state connectivity_state, grpc_error* error) override;
99
+ grpc_connectivity_state connectivity_state) override;
100
100
 
101
101
  grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
102
102
  };
@@ -119,7 +119,6 @@ class RoundRobin : public LoadBalancingPolicy {
119
119
  }
120
120
 
121
121
  ~RoundRobinSubchannelList() {
122
- GRPC_ERROR_UNREF(last_transient_failure_error_);
123
122
  RoundRobin* p = static_cast<RoundRobin*>(policy());
124
123
  p->Unref(DEBUG_LOCATION, "subchannel_list");
125
124
  }
@@ -129,11 +128,8 @@ class RoundRobin : public LoadBalancingPolicy {
129
128
 
130
129
  // Updates the counters of subchannels in each state when a
131
130
  // subchannel transitions from old_state to new_state.
132
- // transient_failure_error is the error that is reported when
133
- // new_state is TRANSIENT_FAILURE.
134
131
  void UpdateStateCountersLocked(grpc_connectivity_state old_state,
135
- grpc_connectivity_state new_state,
136
- grpc_error* transient_failure_error);
132
+ grpc_connectivity_state new_state);
137
133
 
138
134
  // If this subchannel list is the RR policy's current subchannel
139
135
  // list, updates the RR policy's connectivity state based on the
@@ -148,7 +144,6 @@ class RoundRobin : public LoadBalancingPolicy {
148
144
  size_t num_ready_ = 0;
149
145
  size_t num_connecting_ = 0;
150
146
  size_t num_transient_failure_ = 0;
151
- grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
152
147
  };
153
148
 
154
149
  class Picker : public SubchannelPicker {
@@ -193,7 +188,7 @@ class RoundRobin : public LoadBalancingPolicy {
193
188
  bool shutdown_ = false;
194
189
  /// Lock and data used to capture snapshots of this channel's child
195
190
  /// channels and subchannels. This data is consumed by channelz.
196
- gpr_mu child_refs_mu_;
191
+ Mutex child_refs_mu_;
197
192
  channelz::ChildRefsList child_subchannels_;
198
193
  channelz::ChildRefsList child_channels_;
199
194
  };
@@ -217,7 +212,7 @@ RoundRobin::Picker::Picker(RoundRobin* parent,
217
212
  // TODO(roth): rand(3) is not thread-safe. This should be replaced with
218
213
  // something better as part of https://github.com/grpc/grpc/issues/17891.
219
214
  last_picked_index_ = rand() % subchannels_.size();
220
- if (grpc_lb_round_robin_trace.enabled()) {
215
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
221
216
  gpr_log(GPR_INFO,
222
217
  "[RR %p picker %p] created picker from subchannel_list=%p "
223
218
  "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR,
@@ -229,7 +224,7 @@ RoundRobin::Picker::Picker(RoundRobin* parent,
229
224
  RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick,
230
225
  grpc_error** error) {
231
226
  last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size();
232
- if (grpc_lb_round_robin_trace.enabled()) {
227
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
233
228
  gpr_log(GPR_INFO,
234
229
  "[RR %p picker %p] returning index %" PRIuPTR
235
230
  ", connected_subchannel=%p",
@@ -245,24 +240,22 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick,
245
240
  //
246
241
 
247
242
  RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) {
248
- gpr_mu_init(&child_refs_mu_);
249
- if (grpc_lb_round_robin_trace.enabled()) {
243
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
250
244
  gpr_log(GPR_INFO, "[RR %p] Created", this);
251
245
  }
252
246
  }
253
247
 
254
248
  RoundRobin::~RoundRobin() {
255
- if (grpc_lb_round_robin_trace.enabled()) {
249
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
256
250
  gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this);
257
251
  }
258
- gpr_mu_destroy(&child_refs_mu_);
259
252
  GPR_ASSERT(subchannel_list_ == nullptr);
260
253
  GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
261
254
  }
262
255
 
263
256
  void RoundRobin::ShutdownLocked() {
264
257
  AutoChildRefsUpdater guard(this);
265
- if (grpc_lb_round_robin_trace.enabled()) {
258
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
266
259
  gpr_log(GPR_INFO, "[RR %p] Shutting down", this);
267
260
  }
268
261
  shutdown_ = true;
@@ -317,11 +310,10 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
317
310
  // subchannel already used by some other channel may have a non-IDLE
318
311
  // state.
319
312
  for (size_t i = 0; i < num_subchannels(); ++i) {
320
- grpc_error* error = GRPC_ERROR_NONE;
321
313
  grpc_connectivity_state state =
322
- subchannel(i)->CheckConnectivityStateLocked(&error);
314
+ subchannel(i)->CheckConnectivityStateLocked();
323
315
  if (state != GRPC_CHANNEL_IDLE) {
324
- subchannel(i)->UpdateConnectivityStateLocked(state, error);
316
+ subchannel(i)->UpdateConnectivityStateLocked(state);
325
317
  }
326
318
  }
327
319
  // Start connectivity watch for each subchannel.
@@ -335,8 +327,7 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
335
327
  }
336
328
 
337
329
  void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
338
- grpc_connectivity_state old_state, grpc_connectivity_state new_state,
339
- grpc_error* transient_failure_error) {
330
+ grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
340
331
  GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN);
341
332
  GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN);
342
333
  if (old_state == GRPC_CHANNEL_READY) {
@@ -356,8 +347,6 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked(
356
347
  } else if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
357
348
  ++num_transient_failure_;
358
349
  }
359
- GRPC_ERROR_UNREF(last_transient_failure_error_);
360
- last_transient_failure_error_ = transient_failure_error;
361
350
  }
362
351
 
363
352
  // Sets the RR policy's connectivity state and generates a new picker based
@@ -384,20 +373,21 @@ void RoundRobin::RoundRobinSubchannelList::
384
373
  if (num_ready_ > 0) {
385
374
  /* 1) READY */
386
375
  p->channel_control_helper()->UpdateState(
387
- GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
388
- UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
376
+ GRPC_CHANNEL_READY, UniquePtr<SubchannelPicker>(New<Picker>(p, this)));
389
377
  } else if (num_connecting_ > 0) {
390
378
  /* 2) CONNECTING */
391
379
  p->channel_control_helper()->UpdateState(
392
- GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
380
+ GRPC_CHANNEL_CONNECTING,
393
381
  UniquePtr<SubchannelPicker>(New<QueuePicker>(p->Ref())));
394
382
  } else if (num_transient_failure_ == num_subchannels()) {
395
383
  /* 3) TRANSIENT_FAILURE */
384
+ grpc_error* error =
385
+ grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
386
+ "connections to all backends failing"),
387
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
396
388
  p->channel_control_helper()->UpdateState(
397
389
  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_))));
390
+ UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
401
391
  }
402
392
  }
403
393
 
@@ -413,7 +403,7 @@ void RoundRobin::RoundRobinSubchannelList::
413
403
  // therefore we would not be receiving a notification for them.
414
404
  GPR_ASSERT(p->latest_pending_subchannel_list_.get() == this);
415
405
  GPR_ASSERT(!shutting_down());
416
- if (grpc_lb_round_robin_trace.enabled()) {
406
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
417
407
  const size_t old_num_subchannels =
418
408
  p->subchannel_list_ != nullptr
419
409
  ? p->subchannel_list_->num_subchannels()
@@ -432,9 +422,9 @@ void RoundRobin::RoundRobinSubchannelList::
432
422
  }
433
423
 
434
424
  void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
435
- grpc_connectivity_state connectivity_state, grpc_error* error) {
425
+ grpc_connectivity_state connectivity_state) {
436
426
  RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
437
- if (grpc_lb_round_robin_trace.enabled()) {
427
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
438
428
  gpr_log(
439
429
  GPR_INFO,
440
430
  "[RR %p] connectivity changed for subchannel %p, subchannel_list %p "
@@ -445,12 +435,12 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked(
445
435
  grpc_connectivity_state_name(connectivity_state));
446
436
  }
447
437
  subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_,
448
- connectivity_state, error);
438
+ connectivity_state);
449
439
  last_connectivity_state_ = connectivity_state;
450
440
  }
451
441
 
452
442
  void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
453
- grpc_connectivity_state connectivity_state, grpc_error* error) {
443
+ grpc_connectivity_state connectivity_state) {
454
444
  RoundRobin* p = static_cast<RoundRobin*>(subchannel_list()->policy());
455
445
  GPR_ASSERT(subchannel() != nullptr);
456
446
  // If the new state is TRANSIENT_FAILURE, re-resolve.
@@ -459,7 +449,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
459
449
  // when the subchannel list was created, we'd wind up in a constant
460
450
  // loop of re-resolution.
461
451
  if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
462
- if (grpc_lb_round_robin_trace.enabled()) {
452
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
463
453
  gpr_log(GPR_INFO,
464
454
  "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. "
465
455
  "Requesting re-resolution",
@@ -470,20 +460,20 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked(
470
460
  // Renew connectivity watch.
471
461
  RenewConnectivityWatchLocked();
472
462
  // Update state counters.
473
- UpdateConnectivityStateLocked(connectivity_state, error);
463
+ UpdateConnectivityStateLocked(connectivity_state);
474
464
  // Update overall state and renew notification.
475
465
  subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked();
476
466
  }
477
467
 
478
468
  void RoundRobin::UpdateLocked(UpdateArgs args) {
479
469
  AutoChildRefsUpdater guard(this);
480
- if (grpc_lb_round_robin_trace.enabled()) {
470
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
481
471
  gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
482
472
  this, args.addresses.size());
483
473
  }
484
474
  // Replace latest_pending_subchannel_list_.
485
475
  if (latest_pending_subchannel_list_ != nullptr) {
486
- if (grpc_lb_round_robin_trace.enabled()) {
476
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) {
487
477
  gpr_log(GPR_INFO,
488
478
  "[RR %p] Shutting down previous pending subchannel list %p", this,
489
479
  latest_pending_subchannel_list_.get());
@@ -494,9 +484,11 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
494
484
  if (latest_pending_subchannel_list_->num_subchannels() == 0) {
495
485
  // If the new list is empty, immediately promote the new list to the
496
486
  // current list and transition to TRANSIENT_FAILURE.
497
- grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update");
487
+ grpc_error* error =
488
+ grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
489
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
498
490
  channel_control_helper()->UpdateState(
499
- GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
491
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
500
492
  UniquePtr<SubchannelPicker>(New<TransientFailurePicker>(error)));
501
493
  subchannel_list_ = std::move(latest_pending_subchannel_list_);
502
494
  } else if (subchannel_list_ == nullptr) {
@@ -511,6 +503,11 @@ void RoundRobin::UpdateLocked(UpdateArgs args) {
511
503
  }
512
504
  }
513
505
 
506
+ class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig {
507
+ public:
508
+ const char* name() const override { return kRoundRobin; }
509
+ };
510
+
514
511
  //
515
512
  // factory
516
513
  //
@@ -523,6 +520,15 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory {
523
520
  }
524
521
 
525
522
  const char* name() const override { return kRoundRobin; }
523
+
524
+ RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
525
+ const grpc_json* json, grpc_error** error) const override {
526
+ if (json != nullptr) {
527
+ GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0);
528
+ }
529
+ return RefCountedPtr<ParsedLoadBalancingConfig>(
530
+ New<ParsedRoundRobinConfig>());
531
+ }
526
532
  };
527
533
 
528
534
  } // namespace