grpc 1.22.0 → 1.23.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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +487 -649
  3. data/include/grpc/grpc_security.h +25 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +11 -2
  5. data/include/grpc/impl/codegen/port_platform.h +12 -0
  6. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
  7. data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
  8. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
  9. data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
  10. data/src/core/ext/filters/client_channel/connector.h +10 -2
  11. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
  12. data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
  13. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
  14. data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
  19. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
  20. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
  22. data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
  23. data/src/core/ext/filters/client_channel/resolver.h +3 -11
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
  32. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
  33. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
  34. data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
  35. data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
  36. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
  37. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
  38. data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
  39. data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
  40. data/src/core/ext/filters/client_channel/subchannel.h +65 -45
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
  42. data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
  43. data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
  44. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  45. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
  46. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
  47. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
  49. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
  50. data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
  51. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  52. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
  53. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
  59. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
  60. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
  62. data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
  66. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  67. data/src/core/lib/channel/channelz.cc +80 -33
  68. data/src/core/lib/channel/channelz.h +28 -13
  69. data/src/core/lib/compression/compression.cc +1 -2
  70. data/src/core/lib/compression/compression_args.cc +13 -6
  71. data/src/core/lib/compression/compression_args.h +3 -2
  72. data/src/core/lib/compression/compression_internal.cc +1 -1
  73. data/src/core/lib/gpr/env_linux.cc +10 -21
  74. data/src/core/lib/gpr/env_posix.cc +0 -5
  75. data/src/core/lib/gpr/string.cc +7 -2
  76. data/src/core/lib/gpr/string.h +1 -0
  77. data/src/core/lib/gpr/sync_posix.cc +0 -129
  78. data/src/core/lib/gprpp/debug_location.h +3 -2
  79. data/src/core/lib/gprpp/fork.cc +14 -21
  80. data/src/core/lib/gprpp/fork.h +15 -4
  81. data/src/core/lib/gprpp/host_port.cc +118 -0
  82. data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
  83. data/src/core/lib/gprpp/map.h +25 -0
  84. data/src/core/lib/gprpp/memory.h +26 -9
  85. data/src/core/lib/gprpp/ref_counted.h +63 -21
  86. data/src/core/lib/gprpp/string_view.h +143 -0
  87. data/src/core/lib/gprpp/thd.h +10 -1
  88. data/src/core/lib/gprpp/thd_posix.cc +25 -0
  89. data/src/core/lib/gprpp/thd_windows.cc +9 -1
  90. data/src/core/lib/http/httpcli_security_connector.cc +3 -1
  91. data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
  92. data/src/core/lib/iomgr/cfstream_handle.h +8 -2
  93. data/src/core/lib/iomgr/combiner.cc +4 -4
  94. data/src/core/lib/iomgr/error.cc +18 -8
  95. data/src/core/lib/iomgr/error.h +2 -0
  96. data/src/core/lib/iomgr/ev_posix.cc +4 -2
  97. data/src/core/lib/iomgr/executor.cc +4 -1
  98. data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
  99. data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
  100. data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
  101. data/src/core/lib/iomgr/executor/threadpool.h +153 -0
  102. data/src/core/lib/iomgr/fork_posix.cc +4 -2
  103. data/src/core/lib/iomgr/iocp_windows.cc +2 -2
  104. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
  105. data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
  106. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  107. data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
  108. data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
  109. data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
  110. data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
  111. data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
  112. data/src/core/lib/iomgr/socket_windows.h +1 -1
  113. data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
  114. data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
  115. data/src/core/lib/iomgr/tcp_custom.cc +4 -0
  116. data/src/core/lib/iomgr/tcp_posix.cc +8 -2
  117. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
  118. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  119. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  120. data/src/core/lib/iomgr/timer_custom.cc +1 -0
  121. data/src/core/lib/iomgr/timer_manager.cc +0 -29
  122. data/src/core/lib/security/credentials/credentials.cc +84 -0
  123. data/src/core/lib/security/credentials/credentials.h +58 -2
  124. data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
  125. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
  127. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
  128. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
  129. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
  130. data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
  131. data/src/core/lib/security/security_connector/security_connector.cc +1 -1
  132. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  133. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
  134. data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
  135. data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
  136. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
  137. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
  138. data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
  139. data/src/core/lib/security/util/json_util.cc +19 -5
  140. data/src/core/lib/security/util/json_util.h +3 -1
  141. data/src/core/lib/slice/slice.cc +69 -50
  142. data/src/core/lib/slice/slice_buffer.cc +6 -5
  143. data/src/core/lib/slice/slice_hash_table.h +3 -7
  144. data/src/core/lib/slice/slice_intern.cc +130 -39
  145. data/src/core/lib/slice/slice_internal.h +8 -0
  146. data/src/core/lib/slice/slice_utils.h +120 -0
  147. data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
  148. data/src/core/lib/surface/call.cc +8 -3
  149. data/src/core/lib/surface/channel.cc +31 -8
  150. data/src/core/lib/surface/completion_queue.cc +17 -7
  151. data/src/core/lib/surface/init_secure.cc +4 -1
  152. data/src/core/lib/surface/lame_client.cc +2 -2
  153. data/src/core/lib/surface/server.cc +34 -35
  154. data/src/core/lib/surface/server.h +8 -17
  155. data/src/core/lib/surface/version.cc +1 -1
  156. data/src/core/lib/transport/byte_stream.cc +3 -5
  157. data/src/core/lib/transport/byte_stream.h +1 -2
  158. data/src/core/lib/transport/error_utils.cc +10 -1
  159. data/src/core/lib/transport/metadata.cc +202 -35
  160. data/src/core/lib/transport/metadata.h +81 -6
  161. data/src/core/lib/transport/static_metadata.cc +1257 -465
  162. data/src/core/lib/transport/static_metadata.h +190 -347
  163. data/src/core/lib/transport/timeout_encoding.cc +7 -0
  164. data/src/core/lib/transport/timeout_encoding.h +3 -2
  165. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  166. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
  167. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
  168. data/src/core/tsi/ssl_transport_security.cc +35 -43
  169. data/src/core/tsi/ssl_transport_security.h +2 -1
  170. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  171. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  172. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  173. data/src/ruby/lib/grpc/grpc.rb +1 -1
  174. data/src/ruby/lib/grpc/version.rb +1 -1
  175. metadata +39 -33
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -30,24 +30,27 @@
30
30
  namespace grpc_core {
31
31
  namespace channelz {
32
32
 
33
- SubchannelNode::SubchannelNode(Subchannel* subchannel,
33
+ SubchannelNode::SubchannelNode(const char* target_address,
34
34
  size_t channel_tracer_max_nodes)
35
- : BaseNode(EntityType::kSubchannel),
36
- subchannel_(subchannel),
37
- target_(UniquePtr<char>(gpr_strdup(subchannel_->GetTargetAddress()))),
35
+ : BaseNode(EntityType::kSubchannel,
36
+ UniquePtr<char>(gpr_strdup(target_address))),
37
+ target_(UniquePtr<char>(gpr_strdup(target_address))),
38
38
  trace_(channel_tracer_max_nodes) {}
39
39
 
40
40
  SubchannelNode::~SubchannelNode() {}
41
41
 
42
+ void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) {
43
+ connectivity_state_.Store(state, MemoryOrder::RELAXED);
44
+ }
45
+
46
+ void SubchannelNode::SetChildSocket(RefCountedPtr<SocketNode> socket) {
47
+ MutexLock lock(&socket_mu_);
48
+ child_socket_ = std::move(socket);
49
+ }
50
+
42
51
  void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
43
- grpc_connectivity_state state;
44
- if (subchannel_ == nullptr) {
45
- state = GRPC_CHANNEL_SHUTDOWN;
46
- } else {
47
- state = subchannel_->CheckConnectivityState(
48
- nullptr /* health_check_service_name */,
49
- nullptr /* connected_subchannel */);
50
- }
52
+ grpc_connectivity_state state =
53
+ connectivity_state_.Load(MemoryOrder::RELAXED);
51
54
  json = grpc_json_create_child(nullptr, json, "state", nullptr,
52
55
  GRPC_JSON_OBJECT, false);
53
56
  grpc_json_create_child(nullptr, json, "state",
@@ -87,14 +90,20 @@ grpc_json* SubchannelNode::RenderJson() {
87
90
  call_counter_.PopulateCallCounts(json);
88
91
  json = top_level_json;
89
92
  // populate the child socket.
90
- intptr_t socket_uuid = subchannel_->GetChildSocketUuid();
91
- if (socket_uuid != 0) {
93
+ RefCountedPtr<SocketNode> child_socket;
94
+ {
95
+ MutexLock lock(&socket_mu_);
96
+ child_socket = child_socket_;
97
+ }
98
+ if (child_socket != nullptr && child_socket->uuid() != 0) {
92
99
  grpc_json* array_parent = grpc_json_create_child(
93
100
  nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
94
101
  json_iterator = grpc_json_create_child(json_iterator, array_parent, nullptr,
95
102
  nullptr, GRPC_JSON_OBJECT, false);
96
- grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
97
- socket_uuid);
103
+ grpc_json* sibling_iterator = grpc_json_add_number_string_child(
104
+ json_iterator, nullptr, "socketId", child_socket->uuid());
105
+ grpc_json_create_child(sibling_iterator, json_iterator, "name",
106
+ child_socket->name(), GRPC_JSON_STRING, false);
98
107
  }
99
108
  return top_level_json;
100
109
  }
@@ -34,13 +34,16 @@ namespace channelz {
34
34
 
35
35
  class SubchannelNode : public BaseNode {
36
36
  public:
37
- SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes);
37
+ SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes);
38
38
  ~SubchannelNode() override;
39
39
 
40
- void MarkSubchannelDestroyed() {
41
- GPR_ASSERT(subchannel_ != nullptr);
42
- subchannel_ = nullptr;
43
- }
40
+ // Sets the subchannel's connectivity state without health checking.
41
+ void UpdateConnectivityState(grpc_connectivity_state state);
42
+
43
+ // Used when the subchannel's child socket changes. This should be set when
44
+ // the subchannel's transport is created and set to nullptr when the
45
+ // subchannel unrefs the transport.
46
+ void SetChildSocket(RefCountedPtr<SocketNode> socket);
44
47
 
45
48
  grpc_json* RenderJson() override;
46
49
 
@@ -61,7 +64,9 @@ class SubchannelNode : public BaseNode {
61
64
  private:
62
65
  void PopulateConnectivityState(grpc_json* json);
63
66
 
64
- Subchannel* subchannel_;
67
+ Atomic<grpc_connectivity_state> connectivity_state_{GRPC_CHANNEL_IDLE};
68
+ Mutex socket_mu_;
69
+ RefCountedPtr<SocketNode> child_socket_;
65
70
  UniquePtr<char> target_;
66
71
  CallCountingHelper call_counter_;
67
72
  ChannelTrace trace_;
@@ -22,6 +22,7 @@
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
24
  #include "src/core/lib/channel/channel_stack.h"
25
+ #include "src/core/lib/channel/channelz.h"
25
26
  #include "src/core/lib/iomgr/resolve_address.h"
26
27
  #include "src/core/lib/transport/transport.h"
27
28
 
@@ -48,8 +49,15 @@ typedef struct {
48
49
  /** channel arguments (to be passed to the filters) */
49
50
  grpc_channel_args* channel_args;
50
51
 
51
- /** socket uuid of the connected transport. 0 if not available */
52
- intptr_t socket_uuid;
52
+ /** channelz socket node of the connected transport. nullptr if not available
53
+ */
54
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket;
55
+
56
+ void reset() {
57
+ transport = nullptr;
58
+ channel_args = nullptr;
59
+ socket = nullptr;
60
+ }
53
61
  } grpc_connect_out_args;
54
62
 
55
63
  struct grpc_connector_vtable {
@@ -310,7 +310,8 @@ void HealthCheckClient::CallState::Orphan() {
310
310
  }
311
311
 
312
312
  void HealthCheckClient::CallState::StartCall() {
313
- ConnectedSubchannel::CallArgs args = {
313
+ SubchannelCall::Args args = {
314
+ health_check_client_->connected_subchannel_,
314
315
  &pollent_,
315
316
  GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH,
316
317
  gpr_now(GPR_CLOCK_MONOTONIC), // start_time
@@ -321,8 +322,7 @@ void HealthCheckClient::CallState::StartCall() {
321
322
  0, // parent_data_size
322
323
  };
323
324
  grpc_error* error = GRPC_ERROR_NONE;
324
- call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error)
325
- .release();
325
+ call_ = SubchannelCall::Create(std::move(args), &error).release();
326
326
  // Register after-destruction callback.
327
327
  GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction,
328
328
  this, grpc_schedule_on_exec_ctx);
@@ -31,8 +31,8 @@
31
31
  #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
32
32
  #include "src/core/lib/channel/channel_args.h"
33
33
  #include "src/core/lib/gpr/env.h"
34
- #include "src/core/lib/gpr/host_port.h"
35
34
  #include "src/core/lib/gpr/string.h"
35
+ #include "src/core/lib/gprpp/host_port.h"
36
36
  #include "src/core/lib/slice/b64.h"
37
37
  #include "src/core/lib/uri/uri_parser.h"
38
38
 
@@ -126,17 +126,18 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
126
126
  if (no_proxy_str != nullptr) {
127
127
  static const char* NO_PROXY_SEPARATOR = ",";
128
128
  bool use_proxy = true;
129
- char* server_host;
130
- char* server_port;
131
- if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path,
132
- &server_host, &server_port)) {
129
+ grpc_core::UniquePtr<char> server_host;
130
+ grpc_core::UniquePtr<char> server_port;
131
+ if (!grpc_core::SplitHostPort(
132
+ uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host,
133
+ &server_port)) {
133
134
  gpr_log(GPR_INFO,
134
135
  "unable to split host and port, not checking no_proxy list for "
135
136
  "host '%s'",
136
137
  server_uri);
137
138
  gpr_free(no_proxy_str);
138
139
  } else {
139
- size_t uri_len = strlen(server_host);
140
+ size_t uri_len = strlen(server_host.get());
140
141
  char** no_proxy_hosts;
141
142
  size_t num_no_proxy_hosts;
142
143
  gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts,
@@ -145,8 +146,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
145
146
  char* no_proxy_entry = no_proxy_hosts[i];
146
147
  size_t no_proxy_len = strlen(no_proxy_entry);
147
148
  if (no_proxy_len <= uri_len &&
148
- gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) ==
149
- 0) {
149
+ gpr_stricmp(no_proxy_entry,
150
+ &(server_host.get()[uri_len - no_proxy_len])) == 0) {
150
151
  gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'",
151
152
  server_uri);
152
153
  use_proxy = false;
@@ -157,8 +158,6 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
157
158
  gpr_free(no_proxy_hosts[i]);
158
159
  }
159
160
  gpr_free(no_proxy_hosts);
160
- gpr_free(server_host);
161
- gpr_free(server_port);
162
161
  gpr_free(no_proxy_str);
163
162
  if (!use_proxy) goto no_use_proxy;
164
163
  }
@@ -43,23 +43,8 @@ LoadBalancingPolicy::~LoadBalancingPolicy() {
43
43
  }
44
44
 
45
45
  void LoadBalancingPolicy::Orphan() {
46
- // Invoke ShutdownAndUnrefLocked() inside of the combiner.
47
- // TODO(roth): Is this actually needed? We should already be in the
48
- // combiner here. Note that if we directly call ShutdownLocked(),
49
- // then we can probably remove the hack whereby the helper is
50
- // destroyed at shutdown instead of at destruction.
51
- GRPC_CLOSURE_SCHED(
52
- GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this,
53
- grpc_combiner_scheduler(combiner_)),
54
- GRPC_ERROR_NONE);
55
- }
56
-
57
- void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg,
58
- grpc_error* ignored) {
59
- LoadBalancingPolicy* policy = static_cast<LoadBalancingPolicy*>(arg);
60
- policy->ShutdownLocked();
61
- policy->channel_control_helper_.reset();
62
- policy->Unref();
46
+ ShutdownLocked();
47
+ Unref();
63
48
  }
64
49
 
65
50
  //
@@ -27,10 +27,10 @@
27
27
  #include "src/core/lib/gprpp/abstract.h"
28
28
  #include "src/core/lib/gprpp/orphanable.h"
29
29
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
30
+ #include "src/core/lib/gprpp/string_view.h"
30
31
  #include "src/core/lib/iomgr/combiner.h"
31
32
  #include "src/core/lib/iomgr/polling_entity.h"
32
33
  #include "src/core/lib/transport/connectivity_state.h"
33
- #include "src/core/lib/transport/metadata_batch.h"
34
34
 
35
35
  namespace grpc_core {
36
36
 
@@ -92,14 +92,44 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
92
92
  GRPC_ABSTRACT_BASE_CLASS
93
93
  };
94
94
 
95
+ /// Interface for accessing metadata.
96
+ class MetadataInterface {
97
+ public:
98
+ // Implementations whose iterators fit in intptr_t may internally
99
+ // cast this directly to their iterator type. Otherwise, they may
100
+ // dynamically allocate their iterators and store the address here.
101
+ typedef intptr_t Iterator;
102
+
103
+ virtual ~MetadataInterface() = default;
104
+
105
+ /// Adds a key/value pair.
106
+ /// Does NOT take ownership of \a key or \a value.
107
+ /// Implementations must ensure that the key and value remain alive
108
+ /// until the call ends. If desired, they may be allocated via
109
+ /// CallState::Alloc().
110
+ virtual void Add(StringView key, StringView value) GRPC_ABSTRACT;
111
+
112
+ /// Iteration interface.
113
+ virtual Iterator Begin() const GRPC_ABSTRACT;
114
+ virtual bool IsEnd(Iterator it) const GRPC_ABSTRACT;
115
+ virtual void Next(Iterator* it) const GRPC_ABSTRACT;
116
+ virtual StringView Key(Iterator it) const GRPC_ABSTRACT;
117
+ virtual StringView Value(Iterator it) const GRPC_ABSTRACT;
118
+
119
+ /// Removes the element pointed to by \a it, which is modified to
120
+ /// point to the next element.
121
+ virtual void Erase(Iterator* it) GRPC_ABSTRACT;
122
+
123
+ GRPC_ABSTRACT_BASE_CLASS
124
+ };
125
+
95
126
  /// Arguments used when picking a subchannel for an RPC.
96
127
  struct PickArgs {
97
128
  /// Initial metadata associated with the picking call.
98
129
  /// The LB policy may use the existing metadata to influence its routing
99
130
  /// decision, and it may add new metadata elements to be sent with the
100
131
  /// call to the chosen backend.
101
- // TODO(roth): Provide a more generic metadata API here.
102
- grpc_metadata_batch* initial_metadata = nullptr;
132
+ MetadataInterface* initial_metadata;
103
133
  /// An interface for accessing call state. Can be used to allocate
104
134
  /// data associated with the call in an efficient way.
105
135
  CallState* call_state;
@@ -128,7 +158,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
128
158
 
129
159
  /// Used only if type is PICK_COMPLETE. Will be set to the selected
130
160
  /// subchannel, or nullptr if the LB policy decides to drop the call.
131
- RefCountedPtr<ConnectedSubchannelInterface> connected_subchannel;
161
+ RefCountedPtr<SubchannelInterface> subchannel;
132
162
 
133
163
  /// Used only if type is PICK_TRANSIENT_FAILURE.
134
164
  /// Error to be set when returning a transient failure.
@@ -145,7 +175,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
145
175
  /// however, so any data that needs to be used after returning must
146
176
  /// be copied.
147
177
  void (*recv_trailing_metadata_ready)(
148
- void* user_data, grpc_metadata_batch* recv_trailing_metadata,
178
+ void* user_data, MetadataInterface* recv_trailing_metadata,
149
179
  CallState* call_state) = nullptr;
150
180
  void* recv_trailing_metadata_ready_user_data = nullptr;
151
181
  };
@@ -282,6 +312,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
282
312
 
283
313
  grpc_pollset_set* interested_parties() const { return interested_parties_; }
284
314
 
315
+ // Note: This must be invoked while holding the combiner.
285
316
  void Orphan() override;
286
317
 
287
318
  // A picker that returns PICK_QUEUE for all picks.
@@ -322,7 +353,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
322
353
 
323
354
  // Note: LB policies MUST NOT call any method on the helper from their
324
355
  // constructor.
325
- // Note: This will return null after ShutdownLocked() has been called.
326
356
  ChannelControlHelper* channel_control_helper() const {
327
357
  return channel_control_helper_.get();
328
358
  }
@@ -331,8 +361,6 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
331
361
  virtual void ShutdownLocked() GRPC_ABSTRACT;
332
362
 
333
363
  private:
334
- static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored);
335
-
336
364
  /// Combiner under which LB policy actions take place.
337
365
  grpc_combiner* combiner_;
338
366
  /// Owned pointer to interested parties in load balancing decisions.
@@ -20,9 +20,12 @@
20
20
 
21
21
  #include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
22
22
 
23
+ #include <string.h>
24
+
23
25
  #include <grpc/support/atm.h>
24
26
  #include <grpc/support/log.h>
25
27
 
28
+ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
26
29
  #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
27
30
  #include "src/core/lib/iomgr/error.h"
28
31
  #include "src/core/lib/profiling/timers.h"
@@ -95,22 +98,33 @@ static void start_transport_stream_op_batch(
95
98
  GPR_TIMER_SCOPE("clr_start_transport_stream_op_batch", 0);
96
99
  // Handle send_initial_metadata.
97
100
  if (batch->send_initial_metadata) {
98
- // Grab client stats object from user_data for LB token metadata.
99
- grpc_linked_mdelem* lb_token =
100
- batch->payload->send_initial_metadata.send_initial_metadata->idx.named
101
- .lb_token;
102
- if (lb_token != nullptr) {
101
+ // Grab client stats object from metadata.
102
+ grpc_linked_mdelem* client_stats_md =
103
+ batch->payload->send_initial_metadata.send_initial_metadata->list.head;
104
+ for (; client_stats_md != nullptr;
105
+ client_stats_md = client_stats_md->next) {
106
+ if (GRPC_SLICE_START_PTR(GRPC_MDKEY(client_stats_md->md)) ==
107
+ static_cast<const void*>(grpc_core::kGrpcLbClientStatsMetadataKey)) {
108
+ break;
109
+ }
110
+ }
111
+ if (client_stats_md != nullptr) {
103
112
  grpc_core::GrpcLbClientStats* client_stats =
104
- static_cast<grpc_core::GrpcLbClientStats*>(grpc_mdelem_get_user_data(
105
- lb_token->md, grpc_core::GrpcLbClientStats::Destroy));
113
+ const_cast<grpc_core::GrpcLbClientStats*>(
114
+ reinterpret_cast<const grpc_core::GrpcLbClientStats*>(
115
+ GRPC_SLICE_START_PTR(GRPC_MDVALUE(client_stats_md->md))));
106
116
  if (client_stats != nullptr) {
107
- calld->client_stats = client_stats->Ref();
117
+ calld->client_stats.reset(client_stats);
108
118
  // Intercept completion.
109
119
  calld->original_on_complete_for_send = batch->on_complete;
110
120
  GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send,
111
121
  calld, grpc_schedule_on_exec_ctx);
112
122
  batch->on_complete = &calld->on_complete_for_send;
113
123
  }
124
+ // Remove metadata so it doesn't go out on the wire.
125
+ grpc_metadata_batch_remove(
126
+ batch->payload->send_initial_metadata.send_initial_metadata,
127
+ client_stats_md);
114
128
  }
115
129
  }
116
130
  // Intercept completion of recv_initial_metadata.
@@ -84,7 +84,6 @@
84
84
  #include "src/core/lib/backoff/backoff.h"
85
85
  #include "src/core/lib/channel/channel_args.h"
86
86
  #include "src/core/lib/channel/channel_stack.h"
87
- #include "src/core/lib/gpr/host_port.h"
88
87
  #include "src/core/lib/gpr/string.h"
89
88
  #include "src/core/lib/gprpp/manual_constructor.h"
90
89
  #include "src/core/lib/gprpp/memory.h"
@@ -109,11 +108,15 @@
109
108
  #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000
110
109
 
111
110
  #define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token"
111
+ #define GRPC_ARG_GRPCLB_ADDRESS_CLIENT_STATS "grpc.grpclb_address_client_stats"
112
112
 
113
113
  namespace grpc_core {
114
114
 
115
115
  TraceFlag grpc_lb_glb_trace(false, "glb");
116
116
 
117
+ const char kGrpcLbClientStatsMetadataKey[] = "grpclb_client_stats";
118
+ const char kGrpcLbLbTokenMetadataKey[] = "lb-token";
119
+
117
120
  namespace {
118
121
 
119
122
  constexpr char kGrpclb[] = "grpclb";
@@ -161,9 +164,7 @@ class GrpcLb : public LoadBalancingPolicy {
161
164
  bool seen_serverlist() const { return seen_serverlist_; }
162
165
 
163
166
  private:
164
- // So Delete() can access our private dtor.
165
- template <typename T>
166
- friend void grpc_core::Delete(T*);
167
+ GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
167
168
 
168
169
  ~BalancerCallState();
169
170
 
@@ -448,24 +449,44 @@ UniquePtr<char> GrpcLb::Serverlist::AsText() const {
448
449
  return result;
449
450
  }
450
451
 
451
- // vtable for LB token channel arg.
452
+ // vtables for channel args for LB token and client stats.
452
453
  void* lb_token_copy(void* token) {
453
- return token == nullptr
454
- ? nullptr
455
- : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload;
454
+ return gpr_strdup(static_cast<char*>(token));
456
455
  }
457
- void lb_token_destroy(void* token) {
458
- if (token != nullptr) {
459
- GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token});
460
- }
456
+ void lb_token_destroy(void* token) { gpr_free(token); }
457
+ void* client_stats_copy(void* p) {
458
+ GrpcLbClientStats* client_stats = static_cast<GrpcLbClientStats*>(p);
459
+ client_stats->Ref().release();
460
+ return p;
461
+ }
462
+ void client_stats_destroy(void* p) {
463
+ GrpcLbClientStats* client_stats = static_cast<GrpcLbClientStats*>(p);
464
+ client_stats->Unref();
461
465
  }
462
- int lb_token_cmp(void* token1, void* token2) {
466
+ int equal_cmp(void* p1, void* p2) {
463
467
  // Always indicate a match, since we don't want this channel arg to
464
468
  // affect the subchannel's key in the index.
469
+ // TODO(roth): Is this right? This does prevent us from needlessly
470
+ // recreating the subchannel whenever the LB token or client stats
471
+ // changes (i.e., when the balancer call is terminated and reestablished).
472
+ // However, it means that we don't actually recreate the subchannel,
473
+ // which means that we won't ever switch over to using the new LB
474
+ // token or client stats. A better approach might be to find somewhere
475
+ // other than the subchannel args to store the LB token and client
476
+ // stats. They could be stored in a map and then looked up for each
477
+ // call (although we'd need to make sure our Map<> implementation is
478
+ // performant enough). Or we could do something more complicated whereby
479
+ // we create our own subchannel wrapper to store them, although that would
480
+ // involve a lot of refcounting overhead.
481
+ // Given that we're trying to move from grpclb to xds at this point,
482
+ // and that no one has actually reported any problems with this, we
483
+ // probably won't bother fixing this at this point.
465
484
  return 0;
466
485
  }
467
486
  const grpc_arg_pointer_vtable lb_token_arg_vtable = {
468
- lb_token_copy, lb_token_destroy, lb_token_cmp};
487
+ lb_token_copy, lb_token_destroy, equal_cmp};
488
+ const grpc_arg_pointer_vtable client_stats_arg_vtable = {
489
+ client_stats_copy, client_stats_destroy, equal_cmp};
469
490
 
470
491
  bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) {
471
492
  if (server->drop) return false;
@@ -501,20 +522,14 @@ ServerAddressList GrpcLb::Serverlist::GetServerAddressList(
501
522
  grpc_resolved_address addr;
502
523
  ParseServer(server, &addr);
503
524
  // LB token processing.
504
- grpc_mdelem lb_token;
525
+ char lb_token[GPR_ARRAY_SIZE(server->load_balance_token) + 1];
505
526
  if (server->has_load_balance_token) {
506
527
  const size_t lb_token_max_length =
507
528
  GPR_ARRAY_SIZE(server->load_balance_token);
508
529
  const size_t lb_token_length =
509
530
  strnlen(server->load_balance_token, lb_token_max_length);
510
- grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
511
- server->load_balance_token, lb_token_length);
512
- lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr);
513
- if (client_stats != nullptr) {
514
- GPR_ASSERT(grpc_mdelem_set_user_data(
515
- lb_token, GrpcLbClientStats::Destroy,
516
- client_stats->Ref().release()) == client_stats);
517
- }
531
+ memcpy(lb_token, server->load_balance_token, lb_token_length);
532
+ lb_token[lb_token_length] = '\0';
518
533
  } else {
519
534
  char* uri = grpc_sockaddr_to_uri(&addr);
520
535
  gpr_log(GPR_INFO,
@@ -522,16 +537,21 @@ ServerAddressList GrpcLb::Serverlist::GetServerAddressList(
522
537
  "be used instead",
523
538
  uri);
524
539
  gpr_free(uri);
525
- lb_token = GRPC_MDELEM_LB_TOKEN_EMPTY;
540
+ lb_token[0] = '\0';
526
541
  }
527
542
  // Add address.
528
- grpc_arg arg = grpc_channel_arg_pointer_create(
529
- const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN),
530
- (void*)lb_token.payload, &lb_token_arg_vtable);
531
- grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
543
+ InlinedVector<grpc_arg, 2> args_to_add;
544
+ args_to_add.emplace_back(grpc_channel_arg_pointer_create(
545
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
546
+ &lb_token_arg_vtable));
547
+ if (client_stats != nullptr) {
548
+ args_to_add.emplace_back(grpc_channel_arg_pointer_create(
549
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_CLIENT_STATS), client_stats,
550
+ &client_stats_arg_vtable));
551
+ }
552
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
553
+ nullptr, args_to_add.data(), args_to_add.size());
532
554
  addresses.emplace_back(addr, args);
533
- // Clean up.
534
- GRPC_MDELEM_UNREF(lb_token);
535
555
  }
536
556
  return addresses;
537
557
  }
@@ -575,27 +595,36 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) {
575
595
  result = child_picker_->Pick(args);
576
596
  // If pick succeeded, add LB token to initial metadata.
577
597
  if (result.type == PickResult::PICK_COMPLETE &&
578
- result.connected_subchannel != nullptr) {
579
- const grpc_arg* arg = grpc_channel_args_find(
580
- result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
598
+ result.subchannel != nullptr) {
599
+ // Encode client stats object into metadata for use by
600
+ // client_load_reporting filter.
601
+ const grpc_arg* arg =
602
+ grpc_channel_args_find(result.subchannel->channel_args(),
603
+ GRPC_ARG_GRPCLB_ADDRESS_CLIENT_STATS);
604
+ if (arg != nullptr && arg->type == GRPC_ARG_POINTER &&
605
+ arg->value.pointer.p != nullptr) {
606
+ GrpcLbClientStats* client_stats =
607
+ static_cast<GrpcLbClientStats*>(arg->value.pointer.p);
608
+ client_stats->Ref().release(); // Ref passed via metadata.
609
+ // The metadata value is a hack: we pretend the pointer points to
610
+ // a string and rely on the client_load_reporting filter to know
611
+ // how to interpret it.
612
+ args.initial_metadata->Add(
613
+ kGrpcLbClientStatsMetadataKey,
614
+ StringView(reinterpret_cast<const char*>(client_stats), 0));
615
+ // Update calls-started.
616
+ client_stats->AddCallStarted();
617
+ }
618
+ // Encode the LB token in metadata.
619
+ arg = grpc_channel_args_find(result.subchannel->channel_args(),
620
+ GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
581
621
  if (arg == nullptr) {
582
- gpr_log(GPR_ERROR,
583
- "[grpclb %p picker %p] No LB token for connected subchannel %p",
584
- parent_, this, result.connected_subchannel.get());
622
+ gpr_log(GPR_ERROR, "[grpclb %p picker %p] No LB token for subchannel %p",
623
+ parent_, this, result.subchannel.get());
585
624
  abort();
586
625
  }
587
- grpc_mdelem lb_token = {reinterpret_cast<uintptr_t>(arg->value.pointer.p)};
588
- GPR_ASSERT(!GRPC_MDISNULL(lb_token));
589
- grpc_linked_mdelem* mdelem_storage = static_cast<grpc_linked_mdelem*>(
590
- args.call_state->Alloc(sizeof(grpc_linked_mdelem)));
591
- GPR_ASSERT(grpc_metadata_batch_add_tail(
592
- args.initial_metadata, mdelem_storage,
593
- GRPC_MDELEM_REF(lb_token)) == GRPC_ERROR_NONE);
594
- GrpcLbClientStats* client_stats = static_cast<GrpcLbClientStats*>(
595
- grpc_mdelem_get_user_data(lb_token, GrpcLbClientStats::Destroy));
596
- if (client_stats != nullptr) {
597
- client_stats->AddCallStarted();
598
- }
626
+ args.initial_metadata->Add(kGrpcLbLbTokenMetadataKey,
627
+ static_cast<char*>(arg->value.pointer.p));
599
628
  }
600
629
  return result;
601
630
  }
@@ -1415,10 +1444,10 @@ void GrpcLb::UpdateLocked(UpdateArgs args) {
1415
1444
 
1416
1445
  // Returns the backend addresses extracted from the given addresses.
1417
1446
  ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) {
1418
- void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
1447
+ static const char* lb_token = "";
1419
1448
  grpc_arg arg = grpc_channel_arg_pointer_create(
1420
- const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
1421
- &lb_token_arg_vtable);
1449
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN),
1450
+ const_cast<char*>(lb_token), &lb_token_arg_vtable);
1422
1451
  ServerAddressList backend_addresses;
1423
1452
  for (size_t i = 0; i < addresses.size(); ++i) {
1424
1453
  if (!addresses[i].IsBalancer()) {
@@ -1830,7 +1859,12 @@ bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder,
1830
1859
  grpc_channel_args_find(args, GRPC_ARG_LB_POLICY_NAME);
1831
1860
  if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_STRING &&
1832
1861
  strcmp(channel_arg->value.string, "grpclb") == 0) {
1833
- return grpc_channel_stack_builder_append_filter(
1862
+ // TODO(roth): When we get around to re-attempting
1863
+ // https://github.com/grpc/grpc/pull/16214, we should try to keep
1864
+ // this filter at the very top of the subchannel stack, since that
1865
+ // will minimize the number of metadata elements that the filter
1866
+ // needs to iterate through to find the ClientStats object.
1867
+ return grpc_channel_stack_builder_prepend_filter(
1834
1868
  builder, (const grpc_channel_filter*)arg, nullptr, nullptr);
1835
1869
  }
1836
1870
  return true;