grpc 1.21.0 → 1.22.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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +422 -62
  3. data/include/grpc/grpc_security.h +61 -5
  4. data/include/grpc/grpc_security_constants.h +1 -1
  5. data/include/grpc/impl/codegen/gpr_types.h +1 -1
  6. data/include/grpc/slice.h +2 -2
  7. data/src/core/ext/filters/client_channel/backup_poller.cc +2 -3
  8. data/src/core/ext/filters/client_channel/backup_poller.h +5 -2
  9. data/src/core/ext/filters/client_channel/client_channel.cc +260 -122
  10. data/src/core/ext/filters/client_channel/client_channel.h +0 -8
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -84
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -28
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +2 -8
  14. data/src/core/ext/filters/client_channel/health/health_check_client.cc +5 -4
  15. data/src/core/ext/filters/client_channel/lb_policy.cc +16 -2
  16. data/src/core/ext/filters/client_channel/lb_policy.h +92 -98
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +63 -87
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +6 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +35 -87
  20. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +18 -74
  21. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +167 -217
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +216 -190
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +6 -2
  24. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  25. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +1 -1
  26. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  27. data/src/core/ext/filters/client_channel/resolver.h +1 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +6 -3
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -1
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -0
  31. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -8
  32. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +7 -7
  33. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +28 -64
  34. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +4 -12
  35. data/src/core/ext/filters/client_channel/server_address.cc +4 -6
  36. data/src/core/ext/filters/client_channel/server_address.h +1 -3
  37. data/src/core/ext/filters/client_channel/service_config.cc +20 -22
  38. data/src/core/ext/filters/client_channel/service_config.h +26 -28
  39. data/src/core/ext/filters/client_channel/subchannel.cc +261 -160
  40. data/src/core/ext/filters/client_channel/subchannel.h +97 -23
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +113 -0
  42. data/src/core/ext/filters/message_size/message_size_filter.cc +12 -12
  43. data/src/core/ext/filters/message_size/message_size_filter.h +2 -2
  44. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +50 -2
  45. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
  46. data/src/core/ext/transport/chttp2/transport/frame_data.cc +31 -36
  47. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +3 -2
  48. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +71 -52
  49. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +18 -3
  50. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +5 -12
  51. data/src/core/ext/transport/chttp2/transport/hpack_table.h +10 -1
  52. data/src/core/ext/transport/chttp2/transport/internal.h +3 -3
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +39 -57
  54. data/src/core/lib/channel/channelz.cc +136 -19
  55. data/src/core/lib/channel/channelz.h +36 -40
  56. data/src/core/lib/channel/channelz_registry.cc +74 -106
  57. data/src/core/lib/channel/channelz_registry.h +10 -28
  58. data/src/core/lib/channel/context.h +1 -1
  59. data/src/core/lib/channel/handshaker.cc +6 -0
  60. data/src/core/lib/compression/compression.cc +13 -8
  61. data/src/core/lib/compression/compression_internal.cc +14 -10
  62. data/src/core/lib/compression/compression_internal.h +1 -1
  63. data/src/core/lib/compression/stream_compression.cc +3 -2
  64. data/src/core/lib/compression/stream_compression.h +2 -2
  65. data/src/core/lib/compression/stream_compression_gzip.cc +9 -9
  66. data/src/core/lib/gpr/env.h +1 -1
  67. data/src/core/lib/gpr/string.cc +8 -1
  68. data/src/core/lib/gpr/string.h +6 -1
  69. data/src/core/lib/gprpp/fork.cc +1 -1
  70. data/src/core/lib/gprpp/fork.h +5 -1
  71. data/src/core/lib/gprpp/global_config.h +9 -0
  72. data/src/core/lib/gprpp/global_config_custom.h +1 -1
  73. data/src/core/lib/gprpp/inlined_vector.h +8 -0
  74. data/src/core/lib/gprpp/map.h +38 -21
  75. data/src/core/lib/gprpp/memory.h +2 -2
  76. data/src/core/lib/gprpp/orphanable.h +1 -1
  77. data/src/core/lib/gprpp/ref_counted.h +9 -4
  78. data/src/core/lib/http/httpcli.cc +3 -3
  79. data/src/core/lib/iomgr/buffer_list.h +1 -1
  80. data/src/core/lib/iomgr/call_combiner.cc +1 -1
  81. data/src/core/lib/iomgr/call_combiner.h +1 -1
  82. data/src/core/lib/iomgr/cfstream_handle.cc +3 -2
  83. data/src/core/lib/iomgr/cfstream_handle.h +4 -0
  84. data/src/core/lib/iomgr/error.cc +3 -3
  85. data/src/core/lib/iomgr/error.h +9 -3
  86. data/src/core/lib/iomgr/error_internal.h +1 -1
  87. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -1
  88. data/src/core/lib/iomgr/ev_posix.cc +3 -3
  89. data/src/core/lib/iomgr/ev_posix.h +3 -2
  90. data/src/core/lib/iomgr/ev_windows.cc +2 -2
  91. data/src/core/lib/iomgr/iomgr.cc +4 -4
  92. data/src/core/lib/iomgr/lockfree_event.cc +1 -1
  93. data/src/core/lib/iomgr/port.h +5 -1
  94. data/src/core/lib/iomgr/tcp_posix.cc +1 -3
  95. data/src/core/lib/iomgr/tcp_server.cc +5 -0
  96. data/src/core/lib/iomgr/tcp_server.h +24 -0
  97. data/src/core/lib/iomgr/tcp_server_custom.cc +11 -9
  98. data/src/core/lib/iomgr/tcp_server_posix.cc +72 -11
  99. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
  100. data/src/core/lib/iomgr/tcp_server_windows.cc +11 -9
  101. data/src/core/lib/iomgr/tcp_uv.cc +5 -6
  102. data/src/core/lib/iomgr/timer.h +2 -1
  103. data/src/core/lib/iomgr/udp_server.cc +2 -2
  104. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -1
  105. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -2
  106. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -2
  107. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  108. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -1
  109. data/src/core/lib/security/transport/auth_filters.h +3 -0
  110. data/src/core/lib/security/transport/client_auth_filter.cc +13 -0
  111. data/src/core/lib/security/transport/security_handshaker.cc +7 -7
  112. data/src/core/lib/slice/b64.h +2 -2
  113. data/src/core/lib/slice/slice.cc +82 -10
  114. data/src/core/lib/slice/slice_buffer.cc +49 -21
  115. data/src/core/lib/slice/slice_hash_table.h +2 -2
  116. data/src/core/lib/slice/slice_intern.cc +15 -16
  117. data/src/core/lib/slice/slice_internal.h +52 -0
  118. data/src/core/lib/slice/slice_string_helpers.cc +10 -1
  119. data/src/core/lib/slice/slice_string_helpers.h +3 -1
  120. data/src/core/lib/slice/slice_utils.h +50 -0
  121. data/src/core/lib/slice/slice_weak_hash_table.h +2 -2
  122. data/src/core/lib/surface/call.cc +14 -8
  123. data/src/core/lib/surface/channel.cc +89 -97
  124. data/src/core/lib/surface/channel.h +60 -6
  125. data/src/core/lib/surface/completion_queue.cc +49 -36
  126. data/src/core/lib/surface/completion_queue.h +2 -1
  127. data/src/core/lib/surface/server.cc +8 -8
  128. data/src/core/lib/surface/validate_metadata.cc +14 -8
  129. data/src/core/lib/surface/validate_metadata.h +13 -2
  130. data/src/core/lib/surface/version.cc +1 -1
  131. data/src/core/lib/transport/metadata.cc +56 -26
  132. data/src/core/lib/transport/metadata.h +91 -75
  133. data/src/core/lib/transport/static_metadata.cc +262 -176
  134. data/src/core/lib/transport/static_metadata.h +272 -180
  135. data/src/core/lib/transport/transport.cc +1 -1
  136. data/src/core/lib/transport/transport.h +8 -2
  137. data/src/core/tsi/alts/handshaker/alts_shared_resource.h +1 -1
  138. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  139. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +5 -2
  140. data/src/ruby/lib/grpc/version.rb +1 -1
  141. metadata +33 -31
@@ -26,19 +26,19 @@
26
26
  #include "src/core/lib/channel/channel_trace.h"
27
27
  #include "src/core/lib/gprpp/inlined_vector.h"
28
28
  #include "src/core/lib/gprpp/manual_constructor.h"
29
+ #include "src/core/lib/gprpp/map.h"
29
30
  #include "src/core/lib/gprpp/ref_counted.h"
30
31
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
32
+ #include "src/core/lib/gprpp/sync.h"
31
33
  #include "src/core/lib/iomgr/error.h"
32
34
  #include "src/core/lib/iomgr/exec_ctx.h"
33
35
  #include "src/core/lib/json/json.h"
34
36
 
35
- // Channel arg key for client channel factory.
36
- #define GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC \
37
- "grpc.channelz_channel_node_creation_func"
37
+ // Channel arg key for channelz node.
38
+ #define GRPC_ARG_CHANNELZ_CHANNEL_NODE "grpc.channelz_channel_node"
38
39
 
39
- // Channel arg key to signal that the channel is an internal channel.
40
- #define GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL \
41
- "grpc.channelz_channel_is_internal_channel"
40
+ // Channel arg key to encode the channelz uuid of the channel's parent.
41
+ #define GRPC_ARG_CHANNELZ_PARENT_UUID "grpc.channelz_parent_uuid"
42
42
 
43
43
  /** This is the default value for whether or not to enable channelz. If
44
44
  * GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */
@@ -54,6 +54,10 @@ namespace grpc_core {
54
54
 
55
55
  namespace channelz {
56
56
 
57
+ // Helpers for getting and setting GRPC_ARG_CHANNELZ_PARENT_UUID.
58
+ grpc_arg MakeParentUuidArg(intptr_t parent_uuid);
59
+ intptr_t GetParentUuidFromArgs(const grpc_channel_args& args);
60
+
57
61
  // TODO(ncteisen), this only contains the uuids of the children for now,
58
62
  // since that is all that is strictly needed. In a future enhancement we will
59
63
  // add human readable names as in the channelz.proto
@@ -147,38 +151,13 @@ class CallCountingHelper {
147
151
  // Handles channelz bookkeeping for channels
148
152
  class ChannelNode : public BaseNode {
149
153
  public:
150
- static RefCountedPtr<ChannelNode> MakeChannelNode(
151
- grpc_channel* channel, size_t channel_tracer_max_nodes,
152
- bool is_top_level_channel);
154
+ ChannelNode(UniquePtr<char> target, size_t channel_tracer_max_nodes,
155
+ intptr_t parent_uuid);
153
156
 
154
- ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
155
- bool is_top_level_channel);
156
- ~ChannelNode() override;
157
+ intptr_t parent_uuid() const { return parent_uuid_; }
157
158
 
158
159
  grpc_json* RenderJson() override;
159
160
 
160
- // template methods. RenderJSON uses these methods to render its JSON
161
- // representation. These are virtual so that children classes may provide
162
- // their specific mechanism for populating these parts of the channelz
163
- // object.
164
- //
165
- // ChannelNode does not have a notion of connectivity state or child refs,
166
- // so it leaves these implementations blank.
167
- //
168
- // This is utilizing the template method design pattern.
169
- //
170
- // TODO(ncteisen): remove these template methods in favor of manual traversal
171
- // and mutation of the grpc_json object.
172
- virtual void PopulateConnectivityState(grpc_json* json) {}
173
- virtual void PopulateChildRefs(grpc_json* json) {}
174
-
175
- void MarkChannelDestroyed() {
176
- GPR_ASSERT(channel_ != nullptr);
177
- channel_ = nullptr;
178
- }
179
-
180
- bool ChannelIsDestroyed() { return channel_ == nullptr; }
181
-
182
161
  // proxy methods to composed classes.
183
162
  void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
184
163
  trace_.AddTraceEvent(severity, data);
@@ -193,13 +172,35 @@ class ChannelNode : public BaseNode {
193
172
  void RecordCallFailed() { call_counter_.RecordCallFailed(); }
194
173
  void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
195
174
 
175
+ void SetConnectivityState(grpc_connectivity_state state);
176
+
177
+ void AddChildChannel(intptr_t child_uuid);
178
+ void RemoveChildChannel(intptr_t child_uuid);
179
+
180
+ void AddChildSubchannel(intptr_t child_uuid);
181
+ void RemoveChildSubchannel(intptr_t child_uuid);
182
+
196
183
  private:
184
+ void PopulateChildRefs(grpc_json* json);
185
+
197
186
  // to allow the channel trace test to access trace_.
198
187
  friend class testing::ChannelNodePeer;
199
- grpc_channel* channel_ = nullptr;
188
+
200
189
  UniquePtr<char> target_;
201
190
  CallCountingHelper call_counter_;
202
191
  ChannelTrace trace_;
192
+ const intptr_t parent_uuid_;
193
+
194
+ // Least significant bit indicates whether the value is set. Remaining
195
+ // bits are a grpc_connectivity_state value.
196
+ Atomic<int> connectivity_state_{0};
197
+
198
+ Mutex child_mu_; // Guards child maps below.
199
+ // TODO(roth): We don't actually use the values here, only the keys, so
200
+ // these should be sets instead of maps, but we don't currently have a set
201
+ // implementation. Change this if/when we have one.
202
+ Map<intptr_t, bool> child_channels_;
203
+ Map<intptr_t, bool> child_subchannels_;
203
204
  };
204
205
 
205
206
  // Handles channelz bookkeeping for servers
@@ -285,11 +286,6 @@ class ListenSocketNode : public BaseNode {
285
286
  UniquePtr<char> local_addr_;
286
287
  };
287
288
 
288
- // Creation functions
289
-
290
- typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,
291
- size_t, bool);
292
-
293
289
  } // namespace channelz
294
290
  } // namespace grpc_core
295
291
 
@@ -18,6 +18,9 @@
18
18
 
19
19
  #include <grpc/impl/codegen/port_platform.h>
20
20
 
21
+ #include <algorithm>
22
+ #include <cstring>
23
+
21
24
  #include "src/core/lib/channel/channel_trace.h"
22
25
  #include "src/core/lib/channel/channelz.h"
23
26
  #include "src/core/lib/channel/channelz_registry.h"
@@ -29,8 +32,6 @@
29
32
  #include <grpc/support/log.h>
30
33
  #include <grpc/support/sync.h>
31
34
 
32
- #include <cstring>
33
-
34
35
  namespace grpc_core {
35
36
  namespace channelz {
36
37
  namespace {
@@ -51,102 +52,58 @@ ChannelzRegistry* ChannelzRegistry::Default() {
51
52
  return g_channelz_registry;
52
53
  }
53
54
 
54
- ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
55
-
56
- ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
57
-
58
55
  void ChannelzRegistry::InternalRegister(BaseNode* node) {
59
56
  MutexLock lock(&mu_);
60
- entities_.push_back(node);
61
57
  node->uuid_ = ++uuid_generator_;
62
- }
63
-
64
- void ChannelzRegistry::MaybePerformCompactionLocked() {
65
- constexpr double kEmptinessTheshold = 1. / 3;
66
- double emptiness_ratio =
67
- double(num_empty_slots_) / double(entities_.capacity());
68
- if (emptiness_ratio > kEmptinessTheshold) {
69
- int front = 0;
70
- for (size_t i = 0; i < entities_.size(); ++i) {
71
- if (entities_[i] != nullptr) {
72
- entities_[front++] = entities_[i];
73
- }
74
- }
75
- for (int i = 0; i < num_empty_slots_; ++i) {
76
- entities_.pop_back();
77
- }
78
- num_empty_slots_ = 0;
79
- }
80
- }
81
-
82
- int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid,
83
- bool direct_hit_needed) {
84
- int left = 0;
85
- int right = int(entities_.size() - 1);
86
- while (left <= right) {
87
- int true_middle = left + (right - left) / 2;
88
- int first_non_null = true_middle;
89
- while (first_non_null < right && entities_[first_non_null] == nullptr) {
90
- first_non_null++;
91
- }
92
- if (entities_[first_non_null] == nullptr) {
93
- right = true_middle - 1;
94
- continue;
95
- }
96
- intptr_t uuid = entities_[first_non_null]->uuid();
97
- if (uuid == target_uuid) {
98
- return int(first_non_null);
99
- }
100
- if (uuid < target_uuid) {
101
- left = first_non_null + 1;
102
- } else {
103
- right = true_middle - 1;
104
- }
105
- }
106
- return direct_hit_needed ? -1 : left;
58
+ node_map_[node->uuid_] = node;
107
59
  }
108
60
 
109
61
  void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
110
62
  GPR_ASSERT(uuid >= 1);
111
63
  MutexLock lock(&mu_);
112
64
  GPR_ASSERT(uuid <= uuid_generator_);
113
- int idx = FindByUuidLocked(uuid, true);
114
- GPR_ASSERT(idx >= 0);
115
- entities_[idx] = nullptr;
116
- num_empty_slots_++;
117
- MaybePerformCompactionLocked();
65
+ node_map_.erase(uuid);
118
66
  }
119
67
 
120
- BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) {
68
+ RefCountedPtr<BaseNode> ChannelzRegistry::InternalGet(intptr_t uuid) {
121
69
  MutexLock lock(&mu_);
122
70
  if (uuid < 1 || uuid > uuid_generator_) {
123
71
  return nullptr;
124
72
  }
125
- int idx = FindByUuidLocked(uuid, true);
126
- return idx < 0 ? nullptr : entities_[idx];
73
+ auto it = node_map_.find(uuid);
74
+ if (it == node_map_.end()) return nullptr;
75
+ // Found node. Return only if its refcount is not zero (i.e., when we
76
+ // know that there is no other thread about to destroy it).
77
+ BaseNode* node = it->second;
78
+ if (!node->RefIfNonZero()) return nullptr;
79
+ return RefCountedPtr<BaseNode>(node);
127
80
  }
128
81
 
129
82
  char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
130
- MutexLock lock(&mu_);
131
83
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
132
84
  grpc_json* json = top_level_json;
133
85
  grpc_json* json_iterator = nullptr;
134
- InlinedVector<BaseNode*, 10> top_level_channels;
135
- bool reached_pagination_limit = false;
136
- int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0);
137
- for (size_t i = start_idx; i < entities_.size(); ++i) {
138
- if (entities_[i] != nullptr &&
139
- entities_[i]->type() ==
140
- grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel &&
141
- entities_[i]->uuid() >= start_channel_id) {
142
- // check if we are over pagination limit to determine if we need to set
143
- // the "end" element. If we don't go through this block, we know that
144
- // when the loop terminates, we have <= to kPaginationLimit.
145
- if (top_level_channels.size() == kPaginationLimit) {
146
- reached_pagination_limit = true;
147
- break;
86
+ InlinedVector<RefCountedPtr<BaseNode>, 10> top_level_channels;
87
+ RefCountedPtr<BaseNode> node_after_pagination_limit;
88
+ {
89
+ MutexLock lock(&mu_);
90
+ for (auto it = node_map_.lower_bound(start_channel_id);
91
+ it != node_map_.end(); ++it) {
92
+ BaseNode* node = it->second;
93
+ if (node->type() == BaseNode::EntityType::kTopLevelChannel &&
94
+ node->RefIfNonZero()) {
95
+ // Check if we are over pagination limit to determine if we need to set
96
+ // the "end" element. If we don't go through this block, we know that
97
+ // when the loop terminates, we have <= to kPaginationLimit.
98
+ // Note that because we have already increased this node's
99
+ // refcount, we need to decrease it, but we can't unref while
100
+ // holding the lock, because this may lead to a deadlock.
101
+ if (top_level_channels.size() == kPaginationLimit) {
102
+ node_after_pagination_limit.reset(node);
103
+ break;
104
+ }
105
+ top_level_channels.emplace_back(node);
148
106
  }
149
- top_level_channels.push_back(entities_[i]);
150
107
  }
151
108
  }
152
109
  if (!top_level_channels.empty()) {
@@ -159,7 +116,7 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
159
116
  grpc_json_link_child(array_parent, channel_json, json_iterator);
160
117
  }
161
118
  }
162
- if (!reached_pagination_limit) {
119
+ if (node_after_pagination_limit == nullptr) {
163
120
  grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE,
164
121
  false);
165
122
  }
@@ -169,26 +126,30 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
169
126
  }
170
127
 
171
128
  char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
172
- MutexLock lock(&mu_);
173
129
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
174
130
  grpc_json* json = top_level_json;
175
131
  grpc_json* json_iterator = nullptr;
176
- InlinedVector<BaseNode*, 10> servers;
177
- bool reached_pagination_limit = false;
178
- int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0);
179
- for (size_t i = start_idx; i < entities_.size(); ++i) {
180
- if (entities_[i] != nullptr &&
181
- entities_[i]->type() ==
182
- grpc_core::channelz::BaseNode::EntityType::kServer &&
183
- entities_[i]->uuid() >= start_server_id) {
184
- // check if we are over pagination limit to determine if we need to set
185
- // the "end" element. If we don't go through this block, we know that
186
- // when the loop terminates, we have <= to kPaginationLimit.
187
- if (servers.size() == kPaginationLimit) {
188
- reached_pagination_limit = true;
189
- break;
132
+ InlinedVector<RefCountedPtr<BaseNode>, 10> servers;
133
+ RefCountedPtr<BaseNode> node_after_pagination_limit;
134
+ {
135
+ MutexLock lock(&mu_);
136
+ for (auto it = node_map_.lower_bound(start_server_id);
137
+ it != node_map_.end(); ++it) {
138
+ BaseNode* node = it->second;
139
+ if (node->type() == BaseNode::EntityType::kServer &&
140
+ node->RefIfNonZero()) {
141
+ // Check if we are over pagination limit to determine if we need to set
142
+ // the "end" element. If we don't go through this block, we know that
143
+ // when the loop terminates, we have <= to kPaginationLimit.
144
+ // Note that because we have already increased this node's
145
+ // refcount, we need to decrease it, but we can't unref while
146
+ // holding the lock, because this may lead to a deadlock.
147
+ if (servers.size() == kPaginationLimit) {
148
+ node_after_pagination_limit.reset(node);
149
+ break;
150
+ }
151
+ servers.emplace_back(node);
190
152
  }
191
- servers.push_back(entities_[i]);
192
153
  }
193
154
  }
194
155
  if (!servers.empty()) {
@@ -201,7 +162,7 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
201
162
  grpc_json_link_child(array_parent, server_json, json_iterator);
202
163
  }
203
164
  }
204
- if (!reached_pagination_limit) {
165
+ if (node_after_pagination_limit == nullptr) {
205
166
  grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE,
206
167
  false);
207
168
  }
@@ -211,14 +172,21 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
211
172
  }
212
173
 
213
174
  void ChannelzRegistry::InternalLogAllEntities() {
214
- MutexLock lock(&mu_);
215
- for (size_t i = 0; i < entities_.size(); ++i) {
216
- if (entities_[i] != nullptr) {
217
- char* json = entities_[i]->RenderJsonString();
218
- gpr_log(GPR_INFO, "%s", json);
219
- gpr_free(json);
175
+ InlinedVector<RefCountedPtr<BaseNode>, 10> nodes;
176
+ {
177
+ MutexLock lock(&mu_);
178
+ for (auto& p : node_map_) {
179
+ BaseNode* node = p.second;
180
+ if (node->RefIfNonZero()) {
181
+ nodes.emplace_back(node);
182
+ }
220
183
  }
221
184
  }
185
+ for (size_t i = 0; i < nodes.size(); ++i) {
186
+ char* json = nodes[i]->RenderJsonString();
187
+ gpr_log(GPR_INFO, "%s", json);
188
+ gpr_free(json);
189
+ }
222
190
  }
223
191
 
224
192
  } // namespace channelz
@@ -234,7 +202,7 @@ char* grpc_channelz_get_servers(intptr_t start_server_id) {
234
202
  }
235
203
 
236
204
  char* grpc_channelz_get_server(intptr_t server_id) {
237
- grpc_core::channelz::BaseNode* server_node =
205
+ grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> server_node =
238
206
  grpc_core::channelz::ChannelzRegistry::Get(server_id);
239
207
  if (server_node == nullptr ||
240
208
  server_node->type() !=
@@ -254,7 +222,7 @@ char* grpc_channelz_get_server(intptr_t server_id) {
254
222
  char* grpc_channelz_get_server_sockets(intptr_t server_id,
255
223
  intptr_t start_socket_id,
256
224
  intptr_t max_results) {
257
- grpc_core::channelz::BaseNode* base_node =
225
+ grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> base_node =
258
226
  grpc_core::channelz::ChannelzRegistry::Get(server_id);
259
227
  if (base_node == nullptr ||
260
228
  base_node->type() != grpc_core::channelz::BaseNode::EntityType::kServer) {
@@ -263,12 +231,12 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id,
263
231
  // This cast is ok since we have just checked to make sure base_node is
264
232
  // actually a server node
265
233
  grpc_core::channelz::ServerNode* server_node =
266
- static_cast<grpc_core::channelz::ServerNode*>(base_node);
234
+ static_cast<grpc_core::channelz::ServerNode*>(base_node.get());
267
235
  return server_node->RenderServerSockets(start_socket_id, max_results);
268
236
  }
269
237
 
270
238
  char* grpc_channelz_get_channel(intptr_t channel_id) {
271
- grpc_core::channelz::BaseNode* channel_node =
239
+ grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> channel_node =
272
240
  grpc_core::channelz::ChannelzRegistry::Get(channel_id);
273
241
  if (channel_node == nullptr ||
274
242
  (channel_node->type() !=
@@ -288,7 +256,7 @@ char* grpc_channelz_get_channel(intptr_t channel_id) {
288
256
  }
289
257
 
290
258
  char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
291
- grpc_core::channelz::BaseNode* subchannel_node =
259
+ grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> subchannel_node =
292
260
  grpc_core::channelz::ChannelzRegistry::Get(subchannel_id);
293
261
  if (subchannel_node == nullptr ||
294
262
  subchannel_node->type() !=
@@ -306,7 +274,7 @@ char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
306
274
  }
307
275
 
308
276
  char* grpc_channelz_get_socket(intptr_t socket_id) {
309
- grpc_core::channelz::BaseNode* socket_node =
277
+ grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> socket_node =
310
278
  grpc_core::channelz::ChannelzRegistry::Get(socket_id);
311
279
  if (socket_node == nullptr ||
312
280
  socket_node->type() !=
@@ -21,19 +21,16 @@
21
21
 
22
22
  #include <grpc/impl/codegen/port_platform.h>
23
23
 
24
+ #include <stdint.h>
25
+
24
26
  #include "src/core/lib/channel/channel_trace.h"
25
27
  #include "src/core/lib/channel/channelz.h"
26
- #include "src/core/lib/gprpp/inlined_vector.h"
27
-
28
- #include <stdint.h>
28
+ #include "src/core/lib/gprpp/map.h"
29
+ #include "src/core/lib/gprpp/sync.h"
29
30
 
30
31
  namespace grpc_core {
31
32
  namespace channelz {
32
33
 
33
- namespace testing {
34
- class ChannelzRegistryPeer;
35
- }
36
-
37
34
  // singleton registry object to track all objects that are needed to support
38
35
  // channelz bookkeeping. All objects share globally distributed uuids.
39
36
  class ChannelzRegistry {
@@ -48,7 +45,9 @@ class ChannelzRegistry {
48
45
  return Default()->InternalRegister(node);
49
46
  }
50
47
  static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
51
- static BaseNode* Get(intptr_t uuid) { return Default()->InternalGet(uuid); }
48
+ static RefCountedPtr<BaseNode> Get(intptr_t uuid) {
49
+ return Default()->InternalGet(uuid);
50
+ }
52
51
 
53
52
  // Returns the allocated JSON string that represents the proto
54
53
  // GetTopChannelsResponse as per channelz.proto.
@@ -67,13 +66,6 @@ class ChannelzRegistry {
67
66
  static void LogAllEntities() { Default()->InternalLogAllEntities(); }
68
67
 
69
68
  private:
70
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
71
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
72
- friend class testing::ChannelzRegistryPeer;
73
-
74
- ChannelzRegistry();
75
- ~ChannelzRegistry();
76
-
77
69
  // Returned the singleton instance of ChannelzRegistry;
78
70
  static ChannelzRegistry* Default();
79
71
 
@@ -86,27 +78,17 @@ class ChannelzRegistry {
86
78
 
87
79
  // if object with uuid has previously been registered as the correct type,
88
80
  // returns the void* associated with that uuid. Else returns nullptr.
89
- BaseNode* InternalGet(intptr_t uuid);
81
+ RefCountedPtr<BaseNode> InternalGet(intptr_t uuid);
90
82
 
91
83
  char* InternalGetTopChannels(intptr_t start_channel_id);
92
84
  char* InternalGetServers(intptr_t start_server_id);
93
85
 
94
- // If entities_ has over a certain threshold of empty slots, it will
95
- // compact the vector and move all used slots to the front.
96
- void MaybePerformCompactionLocked();
97
-
98
- // Performs binary search on entities_ to find the index with that uuid.
99
- // If direct_hit_needed, then will return -1 in case of absence.
100
- // Else, will return idx of the first uuid higher than the target.
101
- int FindByUuidLocked(intptr_t uuid, bool direct_hit_needed);
102
-
103
86
  void InternalLogAllEntities();
104
87
 
105
88
  // protects members
106
- gpr_mu mu_;
107
- InlinedVector<BaseNode*, 20> entities_;
89
+ Mutex mu_;
90
+ Map<intptr_t, BaseNode*> node_map_;
108
91
  intptr_t uuid_generator_ = 0;
109
- int num_empty_slots_ = 0;
110
92
  };
111
93
 
112
94
  } // namespace channelz