aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ncteisen <ncteisen@gmail.com>2018-07-20 14:26:04 -0700
committerGravatar ncteisen <ncteisen@gmail.com>2018-07-20 14:26:04 -0700
commit8cb2d0c64afd9c766ea6b4c41f3125879091d08a (patch)
tree4b1124a4bdcb40612c78612e39f729610a02ee09
parentca32a8a85286ae0c9c94c3eaeaee3100d0304f99 (diff)
Restructure everything
-rw-r--r--src/core/ext/filters/client_channel/client_channel_channelz.cc79
-rw-r--r--src/core/ext/filters/client_channel/client_channel_channelz.h37
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc8
-rw-r--r--src/core/lib/channel/channelz.cc89
-rw-r--r--src/core/lib/channel/channelz.h122
-rw-r--r--src/core/lib/channel/channelz_registry.cc51
-rw-r--r--src/core/lib/channel/channelz_registry.h50
-rw-r--r--test/core/channel/channelz_registry_test.cc30
-rw-r--r--test/core/channel/channelz_test.cc42
9 files changed, 223 insertions, 285 deletions
diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc
index 0688ee2abb..1d72b9c9d2 100644
--- a/src/core/ext/filters/client_channel/client_channel_channelz.cc
+++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc
@@ -20,6 +20,7 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
+#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/connectivity_state.h"
@@ -97,6 +98,38 @@ void ClientChannelNode::PopulateChildRefs(grpc_json* json) {
}
}
+grpc_json* ClientChannelNode::RenderJson() {
+ // We need to track these three json objects to build our object
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
+ grpc_json* json = top_level_json;
+ grpc_json* json_iterator = nullptr;
+ // create and fill the ref child
+ json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
+ GRPC_JSON_OBJECT, false);
+ json = json_iterator;
+ json_iterator = nullptr;
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "channelId", channel_uuid());
+ // reset json iterators to top level object
+ json = top_level_json;
+ json_iterator = nullptr;
+ // create and fill the data child.
+ grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
+ GRPC_JSON_OBJECT, false);
+ json = data;
+ json_iterator = nullptr;
+ PopulateConnectivityState(json);
+ // populate the target.
+ GPR_ASSERT(target_view() != nullptr);
+ grpc_json_create_child(nullptr, json, "target", target_view(),
+ GRPC_JSON_STRING, false);
+ // as CallCountingAndTracingNode to populate trace and call count data.
+ PopulateTrace(json);
+ PopulateCallData(json);
+ PopulateChildRefs(json);
+ return top_level_json;
+}
+
grpc_arg ClientChannelNode::CreateChannelArg() {
return grpc_channel_arg_pointer_create(
const_cast<char*>(GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC),
@@ -111,20 +144,21 @@ RefCountedPtr<ChannelNode> ClientChannelNode::MakeClientChannelNode(
channel, channel_tracer_max_nodes, is_top_level_channel);
}
-ClientChannelSubchannelNode::ClientChannelSubchannelNode(
- size_t channel_tracer_max_nodes, grpc_subchannel* subchannel)
- : SubchannelNode(channel_tracer_max_nodes),
+SubchannelNode::SubchannelNode(grpc_subchannel* subchannel,
+ size_t channel_tracer_max_nodes)
+ : CallCountingAndTracingNode(EntityType::kSubchannel,
+ channel_tracer_max_nodes),
subchannel_(subchannel),
target_(UniquePtr<char>(
- gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {}
+ gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {
+ subchannel_uuid_ = ChannelzRegistry::Register(this);
+}
-void ClientChannelSubchannelNode::PopulateTarget(grpc_json* json) {
- GPR_ASSERT(target_.get() != nullptr);
- grpc_json_create_child(nullptr, json, "target", target_.get(),
- GRPC_JSON_STRING, false);
+SubchannelNode::~SubchannelNode() {
+ ChannelzRegistry::Unregister(subchannel_uuid_);
}
-void ClientChannelSubchannelNode::PopulateConnectivityState(grpc_json* json) {
+void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
grpc_connectivity_state state;
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
@@ -138,5 +172,32 @@ void ClientChannelSubchannelNode::PopulateConnectivityState(grpc_json* json) {
false);
}
+grpc_json* SubchannelNode::RenderJson() {
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
+ grpc_json* json = top_level_json;
+ grpc_json* json_iterator = nullptr;
+ json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
+ GRPC_JSON_OBJECT, false);
+ json = json_iterator;
+ json_iterator = nullptr;
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "subchannelId", subchannel_uuid_);
+ // reset json iterators to top level object
+ json = top_level_json;
+ json_iterator = nullptr;
+ // create and fill the data child.
+ grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
+ GRPC_JSON_OBJECT, false);
+ json = data;
+ json_iterator = nullptr;
+ PopulateConnectivityState(json);
+ GPR_ASSERT(target_.get() != nullptr);
+ grpc_json_create_child(nullptr, json, "target", target_.get(),
+ GRPC_JSON_STRING, false);
+ PopulateTrace(json);
+ PopulateCallData(json);
+ return top_level_json;
+}
+
} // namespace channelz
} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h
index b1bd8db89e..73eea7cecf 100644
--- a/src/core/ext/filters/client_channel/client_channel_channelz.h
+++ b/src/core/ext/filters/client_channel/client_channel_channelz.h
@@ -45,12 +45,7 @@ class ClientChannelNode : public ChannelNode {
grpc_channel* channel, size_t channel_tracer_max_nodes,
bool is_top_level_channel);
- // Override this functionality since client_channels have a notion of
- // channel connectivity.
- void PopulateConnectivityState(grpc_json* json) override;
-
- // Override this functionality since client_channels have subchannels
- void PopulateChildRefs(grpc_json* json) override;
+ grpc_json* RenderJson() override;
// Helper to create a channel arg to ensure this type of ChannelNode is
// created.
@@ -65,35 +60,35 @@ class ClientChannelNode : public ChannelNode {
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
grpc_channel_element* client_channel_;
+
+ // helpers
+ void PopulateConnectivityState(grpc_json* json);
+ void PopulateChildRefs(grpc_json* json);
};
-// Subtype of SubchannelNode that overrides and provides client_channel
-// specific functionality like querying for connectivity_state and
-// subchannel target.
-class ClientChannelSubchannelNode : public SubchannelNode {
+// Handles channelz bookkeeping for sockets
+class SubchannelNode : public CallCountingAndTracingNode {
public:
- ClientChannelSubchannelNode(size_t channel_tracer_max_nodes,
- grpc_subchannel* subchannel);
- ~ClientChannelSubchannelNode() override {}
-
- // Override this functionality since subchannels have a notion of
- // channel connectivity.
- void PopulateConnectivityState(grpc_json* json) override;
-
- // Override this functionality since client_channels subchannels hold
- // their own target.
- void PopulateTarget(grpc_json* json) override;
+ SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes);
+ ~SubchannelNode() override;
void MarkSubchannelDestroyed() {
GPR_ASSERT(subchannel_ != nullptr);
subchannel_ = nullptr;
}
+ grpc_json* RenderJson() override;
+
+ intptr_t subchannel_uuid() { return subchannel_uuid_; }
+
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+ intptr_t subchannel_uuid_;
grpc_subchannel* subchannel_;
UniquePtr<char> target_;
+
+ void PopulateConnectivityState(grpc_json* json);
};
} // namespace channelz
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index 0c3313c5de..8dfbd33ffe 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -135,7 +135,7 @@ struct grpc_subchannel {
/** our alarm */
grpc_timer alarm;
- grpc_core::RefCountedPtr<grpc_core::channelz::ClientChannelSubchannelNode>
+ grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel;
};
@@ -393,9 +393,9 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
size_t channel_tracer_max_nodes =
(size_t)grpc_channel_arg_get_integer(arg, options);
if (channelz_enabled) {
- c->channelz_subchannel = grpc_core::MakeRefCounted<
- grpc_core::channelz::ClientChannelSubchannelNode>(
- channel_tracer_max_nodes, c);
+ c->channelz_subchannel =
+ grpc_core::MakeRefCounted<grpc_core::channelz::SubchannelNode>(
+ c, channel_tracer_max_nodes);
c->channelz_subchannel->trace()->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string("Subchannel created"));
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 7fe086da3c..d7f2d6a9a2 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -41,21 +41,30 @@
namespace grpc_core {
namespace channelz {
-CallCountingBase::CallCountingBase(size_t channel_tracer_max_nodes) {
+char* BaseNode::RenderJsonString() {
+ grpc_json* json = RenderJson();
+ char* json_str = grpc_json_dump_to_string(json, 0);
+ grpc_json_destroy(json);
+ return json_str;
+}
+
+CallCountingAndTracingNode::CallCountingAndTracingNode(
+ EntityType type, size_t channel_tracer_max_nodes)
+ : BaseNode(type) {
trace_.Init(channel_tracer_max_nodes);
gpr_atm_no_barrier_store(&last_call_started_millis_,
(gpr_atm)ExecCtx::Get()->Now());
}
-CallCountingBase::~CallCountingBase() { trace_.Destroy(); }
+CallCountingAndTracingNode::~CallCountingAndTracingNode() { trace_.Destroy(); }
-void CallCountingBase::RecordCallStarted() {
+void CallCountingAndTracingNode::RecordCallStarted() {
gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1);
gpr_atm_no_barrier_store(&last_call_started_millis_,
(gpr_atm)ExecCtx::Get()->Now());
}
-void CallCountingBase::PopulateTrace(grpc_json* json) {
+void CallCountingAndTracingNode::PopulateTrace(grpc_json* json) {
// fill in the channel trace if applicable
grpc_json* trace_json = trace_->RenderJson();
if (trace_json != nullptr) {
@@ -66,7 +75,7 @@ void CallCountingBase::PopulateTrace(grpc_json* json) {
}
}
-void CallCountingBase::PopulateCallData(grpc_json* json) {
+void CallCountingAndTracingNode::PopulateCallData(grpc_json* json) {
grpc_json* json_iterator = nullptr;
if (calls_started_ != 0) {
json_iterator = grpc_json_add_number_string_child(
@@ -87,31 +96,18 @@ void CallCountingBase::PopulateCallData(grpc_json* json) {
gpr_format_timespec(ts), GRPC_JSON_STRING, true);
}
-char* CallCountingBase::RenderJsonString() {
- grpc_json* json = RenderJson();
- char* json_str = grpc_json_dump_to_string(json, 0);
- grpc_json_destroy(json);
- return json_str;
-}
-
ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
bool is_top_level_channel)
- : CallCountingBase(channel_tracer_max_nodes),
+ : CallCountingAndTracingNode(is_top_level_channel
+ ? EntityType::kTopLevelChannel
+ : EntityType::kInternalChannel,
+ channel_tracer_max_nodes),
channel_(channel),
- is_top_level_channel_(is_top_level_channel) {
- target_ = UniquePtr<char>(grpc_channel_get_target(channel_));
- channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this);
+ target_(UniquePtr<char>(grpc_channel_get_target(channel_))) {
+ channel_uuid_ = ChannelzRegistry::Register(this);
}
-ChannelNode::~ChannelNode() {
- ChannelzRegistry::UnregisterChannelNode(channel_uuid_);
-}
-
-void ChannelNode::PopulateTarget(grpc_json* json) {
- GPR_ASSERT(target_.get() != nullptr);
- grpc_json_create_child(nullptr, json, "target", target_.get(),
- GRPC_JSON_STRING, false);
-}
+ChannelNode::~ChannelNode() { ChannelzRegistry::Unregister(channel_uuid_); }
grpc_json* ChannelNode::RenderJson() {
// We need to track these three json objects to build our object
@@ -133,11 +129,13 @@ grpc_json* ChannelNode::RenderJson() {
GRPC_JSON_OBJECT, false);
json = data;
json_iterator = nullptr;
- PopulateConnectivityState(json);
- PopulateTarget(json);
+ // populate the target.
+ GPR_ASSERT(target_.get() != nullptr);
+ grpc_json_create_child(nullptr, json, "target", target_.get(),
+ GRPC_JSON_STRING, false);
+ // as CallCountingAndTracingNode to populate trace and call count data.
PopulateTrace(json);
PopulateCallData(json);
- PopulateChildRefs(json);
return top_level_json;
}
@@ -148,40 +146,5 @@ RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
channel, channel_tracer_max_nodes, is_top_level_channel);
}
-SubchannelNode::SubchannelNode(size_t channel_tracer_max_nodes)
- : CallCountingBase(channel_tracer_max_nodes) {
- subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this);
-}
-
-SubchannelNode::~SubchannelNode() {
- ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_);
-}
-
-grpc_json* SubchannelNode::RenderJson() {
- grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
- grpc_json* json = top_level_json;
- grpc_json* json_iterator = nullptr;
- json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
- GRPC_JSON_OBJECT, false);
- json = json_iterator;
- json_iterator = nullptr;
- json_iterator = grpc_json_add_number_string_child(
- json, json_iterator, "subchannelId", subchannel_uuid_);
- // reset json iterators to top level object
- json = top_level_json;
- json_iterator = nullptr;
- // create and fill the data child.
- grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
- GRPC_JSON_OBJECT, false);
- json = data;
- json_iterator = nullptr;
- PopulateConnectivityState(json);
- PopulateTarget(json);
- PopulateTrace(json);
- PopulateCallData(json);
- PopulateChildRefs(json);
- return top_level_json;
-}
-
} // namespace channelz
} // namespace grpc_core
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 1cd55bab43..1273545663 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -43,30 +43,40 @@ namespace grpc_core {
namespace channelz {
namespace testing {
-class ChannelNodePeer;
+class CallCountingAndTracingNodePeer;
}
// base class for all channelz entities
class BaseNode : public RefCounted<BaseNode> {
public:
- BaseNode() {}
+ // There are only four high level channelz entities. However, to support
+ // GetTopChannelsRequest, we split the Channel entity into two different
+ // types. All children of BaseNode must be one of these types.
+ enum class EntityType {
+ kTopLevelChannel,
+ kInternalChannel,
+ kSubchannel,
+ kServer,
+ kSocket,
+ };
+
+ // we track is_top_level_channel to support GetTopChannels
+ BaseNode(EntityType type) : type_(type) {}
virtual ~BaseNode() {}
- private:
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
-};
+ // All children must implement this function.
+ virtual grpc_json* RenderJson() GRPC_ABSTRACT;
-// Handles channelz bookkeeping for sockets
-// TODO(ncteisen): implement in subsequent PR.
-class SocketNode : public BaseNode {
- public:
- SocketNode() : BaseNode() {}
- ~SocketNode() override {}
+ // Renders the json and returns allocated string that must be freed by the
+ // caller.
+ char* RenderJsonString();
+
+ EntityType type() const { return type_; }
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+ EntityType type_;
};
// This class is the parent for the channelz entities that deal with Channels
@@ -76,16 +86,10 @@ class SocketNode : public BaseNode {
// - track last_call_started_timestamp
// - hold the channel trace.
// - perform common rendering.
-//
-// This class also defines some fat interfaces so that its children can
-// implement the functionality differently. For example, querying the
-// connectivity state looks different for channels than for subchannels, and
-// does not make sense for servers. So servers will not override, and channels
-// and subchannels will override with their own way to query connectivity state.
-class CallCountingBase : public BaseNode {
+class CallCountingAndTracingNode : public BaseNode {
public:
- CallCountingBase(size_t channel_tracer_max_nodes);
- ~CallCountingBase() override;
+ CallCountingAndTracingNode(EntityType type, size_t channel_tracer_max_nodes);
+ ~CallCountingAndTracingNode() override;
void RecordCallStarted();
void RecordCallFailed() {
@@ -96,34 +100,19 @@ class CallCountingBase : public BaseNode {
}
ChannelTrace* trace() { return trace_.get(); }
- // Fat interface for ConnectivityState. Default is to leave it out, however,
- // things like Channel and Subchannel will override with their mechanism
- // for querying connectivity state.
- virtual void PopulateConnectivityState(grpc_json* json) {}
-
- // Fat interface for Targets.
- virtual void PopulateTarget(grpc_json* json) {}
-
- // Fat interface for ChildRefs. Allows children to populate with whatever
- // combination of child_refs, subchannel_refs, and socket_refs is correct.
- virtual void PopulateChildRefs(grpc_json* json) {}
-
- // All children must implement their custom JSON rendering.
- virtual grpc_json* RenderJson() GRPC_ABSTRACT;
-
// Common rendering of the channel trace.
void PopulateTrace(grpc_json* json);
// Common rendering of the call count data and last_call_started_timestamp.
void PopulateCallData(grpc_json* json);
- // Common rendering of grpc_json from RenderJson() to allocated string.
- char* RenderJsonString();
-
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+ // testing peer friend.
+ friend class testing::CallCountingAndTracingNodePeer;
+
gpr_atm calls_started_ = 0;
gpr_atm calls_succeeded_ = 0;
gpr_atm calls_failed_ = 0;
@@ -131,71 +120,64 @@ class CallCountingBase : public BaseNode {
ManualConstructor<ChannelTrace> trace_;
};
-// Handles channelz bookkeeping for servers
-// TODO(ncteisen): implement in subsequent PR.
-class ServerNode : public CallCountingBase {
- public:
- ServerNode(size_t channel_tracer_max_nodes)
- : CallCountingBase(channel_tracer_max_nodes) {}
- ~ServerNode() override {}
-
- private:
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
-};
-
-// Overrides Channel specific functionality.
-class ChannelNode : public CallCountingBase {
+// Handles channelz bookkeeping for channels
+class ChannelNode : public CallCountingAndTracingNode {
public:
static RefCountedPtr<ChannelNode> MakeChannelNode(
grpc_channel* channel, size_t channel_tracer_max_nodes,
bool is_top_level_channel);
+ grpc_json* RenderJson() override;
+
void MarkChannelDestroyed() {
GPR_ASSERT(channel_ != nullptr);
channel_ = nullptr;
}
- grpc_json* RenderJson() override;
-
- void PopulateTarget(grpc_json* json) override;
-
bool ChannelIsDestroyed() { return channel_ == nullptr; }
intptr_t channel_uuid() { return channel_uuid_; }
- bool is_top_level_channel() { return is_top_level_channel_; }
protected:
ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
bool is_top_level_channel);
~ChannelNode() override;
+ // provides view of target for child.
+ char* target_view() { return target_.get(); }
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
- // testing peer friend.
- friend class testing::ChannelNodePeer;
-
grpc_channel* channel_ = nullptr;
UniquePtr<char> target_;
intptr_t channel_uuid_;
- bool is_top_level_channel_ = true;
};
-// Overrides Subchannel specific functionality.
-class SubchannelNode : public CallCountingBase {
+// Handles channelz bookkeeping for servers
+// TODO(ncteisen): implement in subsequent PR.
+class ServerNode : public CallCountingAndTracingNode {
public:
- SubchannelNode(size_t channel_tracer_max_nodes);
- ~SubchannelNode() override;
- grpc_json* RenderJson() override;
- intptr_t subchannel_uuid() { return subchannel_uuid_; }
+ ServerNode(size_t channel_tracer_max_nodes)
+ : CallCountingAndTracingNode(EntityType::kServer,
+ channel_tracer_max_nodes) {}
+ ~ServerNode() override {}
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+};
- intptr_t subchannel_uuid_;
+// Handles channelz bookkeeping for sockets
+// TODO(ncteisen): implement in subsequent PR.
+class SocketNode : public BaseNode {
+ public:
+ SocketNode() : BaseNode(EntityType::kSocket) {}
+ ~SocketNode() override {}
+
+ private:
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
};
// Creation functions
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc
index aeeb6958e4..7f70908989 100644
--- a/src/core/lib/channel/channelz_registry.cc
+++ b/src/core/lib/channel/channelz_registry.cc
@@ -52,54 +52,46 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
-intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) {
+intptr_t ChannelzRegistry::InternalRegister(BaseNode* node) {
mu_guard guard(&mu_);
- entities_.push_back(entry);
+ entities_.push_back(node);
intptr_t uuid = entities_.size();
return uuid;
}
-void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) {
+void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
GPR_ASSERT(uuid >= 1);
mu_guard guard(&mu_);
GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
- GPR_ASSERT(entities_[uuid - 1].type == type);
- entities_[uuid - 1].object = nullptr;
- entities_[uuid - 1].type = EntityType::kUnset;
+ entities_[uuid - 1] = nullptr;
}
-void* ChannelzRegistry::InternalGetEntry(intptr_t uuid, EntityType type) {
+BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) {
mu_guard guard(&mu_);
if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
return nullptr;
}
- if (entities_[uuid - 1].type == type) {
- return entities_[uuid - 1].object;
- } else {
- return nullptr;
- }
+ return entities_[uuid - 1];
}
char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
- InlinedVector<ChannelNode*, 10> top_level_channels;
+ InlinedVector<BaseNode*, 10> top_level_channels;
// uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
// reserved). However, we want to support requests coming in with
// start_channel_id=0, which signifies "give me everything." Hence this
// funky looking line below.
size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
for (size_t i = start_idx; i < entities_.size(); ++i) {
- if (entities_[i].type == EntityType::kChannelNode) {
- ChannelNode* channel_node =
- static_cast<ChannelNode*>(entities_[i].object);
- if (channel_node->is_top_level_channel()) {
- top_level_channels.push_back(channel_node);
- }
+ if (entities_[i] != nullptr &&
+ entities_[i]->type() ==
+ grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) {
+ top_level_channels.push_back(entities_[i]);
}
}
- if (top_level_channels.size() > 0) {
+ if (!top_level_channels.empty()) {
// create list of channels
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false);
@@ -128,9 +120,14 @@ char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
}
char* grpc_channelz_get_channel(intptr_t channel_id) {
- grpc_core::channelz::ChannelNode* channel_node =
- grpc_core::channelz::ChannelzRegistry::GetChannelNode(channel_id);
- if (channel_node == nullptr) {
+ grpc_core::channelz::BaseNode* channel_node =
+ grpc_core::channelz::ChannelzRegistry::Get(channel_id);
+ if (channel_node == nullptr ||
+
+ (channel_node->type() !=
+ grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel &&
+ channel_node->type() !=
+ grpc_core::channelz::BaseNode::EntityType::kInternalChannel)) {
return nullptr;
}
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
@@ -144,9 +141,11 @@ char* grpc_channelz_get_channel(intptr_t channel_id) {
}
char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
- grpc_core::channelz::SubchannelNode* subchannel_node =
- grpc_core::channelz::ChannelzRegistry::GetSubchannelNode(subchannel_id);
- if (subchannel_node == nullptr) {
+ grpc_core::channelz::BaseNode* subchannel_node =
+ grpc_core::channelz::ChannelzRegistry::Get(subchannel_id);
+ if (subchannel_node == nullptr ||
+ subchannel_node->type() !=
+ grpc_core::channelz::BaseNode::EntityType::kSubchannel) {
return nullptr;
}
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h
index 5d7c936726..142c039220 100644
--- a/src/core/lib/channel/channelz_registry.h
+++ b/src/core/lib/channel/channelz_registry.h
@@ -40,32 +40,11 @@ class ChannelzRegistry {
// To be called in grpc_shutdown();
static void Shutdown();
- // Register/Unregister/Get for ChannelNode
- static intptr_t RegisterChannelNode(ChannelNode* channel_node) {
- RegistryEntry entry(channel_node, EntityType::kChannelNode);
- return Default()->InternalRegisterEntry(entry);
- }
- static void UnregisterChannelNode(intptr_t uuid) {
- Default()->InternalUnregisterEntry(uuid, EntityType::kChannelNode);
- }
- static ChannelNode* GetChannelNode(intptr_t uuid) {
- void* gotten = Default()->InternalGetEntry(uuid, EntityType::kChannelNode);
- return gotten == nullptr ? nullptr : static_cast<ChannelNode*>(gotten);
- }
-
- // Register/Unregister/Get for SubchannelNode
- static intptr_t RegisterSubchannelNode(SubchannelNode* channel_node) {
- RegistryEntry entry(channel_node, EntityType::kSubchannelNode);
- return Default()->InternalRegisterEntry(entry);
- }
- static void UnregisterSubchannelNode(intptr_t uuid) {
- Default()->InternalUnregisterEntry(uuid, EntityType::kSubchannelNode);
- }
- static SubchannelNode* GetSubchannelNode(intptr_t uuid) {
- void* gotten =
- Default()->InternalGetEntry(uuid, EntityType::kSubchannelNode);
- return gotten == nullptr ? nullptr : static_cast<SubchannelNode*>(gotten);
+ static intptr_t Register(BaseNode* node) {
+ return Default()->InternalRegister(node);
}
+ static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
+ static BaseNode* Get(intptr_t uuid) { return Default()->InternalGet(uuid); }
// Returns the allocated JSON string that represents the proto
// GetTopChannelsResponse as per channelz.proto.
@@ -74,19 +53,6 @@ class ChannelzRegistry {
}
private:
- enum class EntityType {
- kChannelNode,
- kSubchannelNode,
- kUnset,
- };
-
- struct RegistryEntry {
- RegistryEntry(void* object_in, EntityType type_in)
- : object(object_in), type(type_in) {}
- void* object;
- EntityType type;
- };
-
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
@@ -97,21 +63,21 @@ class ChannelzRegistry {
static ChannelzRegistry* Default();
// globally registers an Entry. Returns its unique uuid
- intptr_t InternalRegisterEntry(const RegistryEntry& entry);
+ intptr_t InternalRegister(BaseNode* node);
// globally unregisters the object that is associated to uuid. Also does
// sanity check that an object doesn't try to unregister the wrong type.
- void InternalUnregisterEntry(intptr_t uuid, EntityType type);
+ void InternalUnregister(intptr_t uuid);
// if object with uuid has previously been registered as the correct type,
// returns the void* associated with that uuid. Else returns nullptr.
- void* InternalGetEntry(intptr_t uuid, EntityType type);
+ BaseNode* InternalGet(intptr_t uuid);
char* InternalGetTopChannels(intptr_t start_channel_id);
// protects entities_ and uuid_
gpr_mu mu_;
- InlinedVector<RegistryEntry, 20> entities_;
+ InlinedVector<BaseNode*, 20> entities_;
};
} // namespace channelz
diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc
index 581e867584..c02d525c81 100644
--- a/test/core/channel/channelz_registry_test.cc
+++ b/test/core/channel/channelz_registry_test.cc
@@ -44,22 +44,22 @@ namespace channelz {
namespace testing {
TEST(ChannelzRegistryTest, UuidStartsAboveZeroTest) {
- ChannelNode* channelz_channel = nullptr;
- intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
+ BaseNode* channelz_channel = nullptr;
+ intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if "
"reserved according to "
"https://github.com/grpc/proposal/blob/master/"
"A14-channelz.md";
- ChannelzRegistry::UnregisterChannelNode(uuid);
+ ChannelzRegistry::Unregister(uuid);
}
TEST(ChannelzRegistryTest, UuidsAreIncreasing) {
- ChannelNode* channelz_channel = nullptr;
+ BaseNode* channelz_channel = nullptr;
std::vector<intptr_t> uuids;
uuids.reserve(10);
for (int i = 0; i < 10; ++i) {
// reregister the same object. It's ok since we are just testing uuids
- uuids.push_back(ChannelzRegistry::RegisterChannelNode(channelz_channel));
+ uuids.push_back(ChannelzRegistry::Register(channelz_channel));
}
for (size_t i = 1; i < uuids.size(); ++i) {
EXPECT_LT(uuids[i - 1], uuids[i]) << "Uuids must always be increasing";
@@ -68,30 +68,30 @@ TEST(ChannelzRegistryTest, UuidsAreIncreasing) {
TEST(ChannelzRegistryTest, RegisterGetTest) {
// we hackily jam an intptr_t into this pointer to check for equality later
- ChannelNode* channelz_channel = (ChannelNode*)42;
- intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
- ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ BaseNode* channelz_channel = (BaseNode*)42;
+ intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
+ BaseNode* retrieved = ChannelzRegistry::Get(uuid);
EXPECT_EQ(channelz_channel, retrieved);
}
TEST(ChannelzRegistryTest, RegisterManyItems) {
// we hackily jam an intptr_t into this pointer to check for equality later
- ChannelNode* channelz_channel = (ChannelNode*)42;
+ BaseNode* channelz_channel = (BaseNode*)42;
for (int i = 0; i < 100; i++) {
- intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
- ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
+ BaseNode* retrieved = ChannelzRegistry::Get(uuid);
EXPECT_EQ(channelz_channel, retrieved);
}
}
TEST(ChannelzRegistryTest, NullIfNotPresentTest) {
// we hackily jam an intptr_t into this pointer to check for equality later
- ChannelNode* channelz_channel = (ChannelNode*)42;
- intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
+ BaseNode* channelz_channel = (BaseNode*)42;
+ intptr_t uuid = ChannelzRegistry::Register(channelz_channel);
// try to pull out a uuid that does not exist.
- ChannelNode* nonexistant = ChannelzRegistry::GetChannelNode(uuid + 1);
+ BaseNode* nonexistant = ChannelzRegistry::Get(uuid + 1);
EXPECT_EQ(nonexistant, nullptr);
- ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ BaseNode* retrieved = ChannelzRegistry::Get(uuid);
EXPECT_EQ(channelz_channel, retrieved);
}
diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc
index b8e65ebfb3..ec1c9f6faf 100644
--- a/test/core/channel/channelz_test.cc
+++ b/test/core/channel/channelz_test.cc
@@ -44,16 +44,17 @@ namespace channelz {
namespace testing {
// testing peer to access channel internals
-class ChannelNodePeer {
+class CallCountingAndTracingNodePeer {
public:
- ChannelNodePeer(ChannelNode* channel) : channel_(channel) {}
+ CallCountingAndTracingNodePeer(CallCountingAndTracingNode* node)
+ : node_(node) {}
grpc_millis last_call_started_millis() {
return (grpc_millis)gpr_atm_no_barrier_load(
- &channel_->last_call_started_millis_);
+ &node_->last_call_started_millis_);
}
private:
- ChannelNode* channel_;
+ CallCountingAndTracingNode* node_;
};
namespace {
@@ -163,16 +164,8 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) {
gpr_free(core_api_json_str);
}
-void ValidateSubchannel(SubchannelNode* subchannel,
- validate_channel_data_args args) {
- char* json_str = subchannel->RenderJsonString();
- grpc::testing::ValidateSubchannelProtoJsonTranslation(json_str);
- ValidateCounters(json_str, args);
- gpr_free(json_str);
-}
-
-grpc_millis GetLastCallStartedMillis(ChannelNode* channel) {
- ChannelNodePeer peer(channel);
+grpc_millis GetLastCallStartedMillis(CallCountingAndTracingNode* channel) {
+ CallCountingAndTracingNodePeer peer(channel);
return peer.last_call_started_millis();
}
@@ -283,29 +276,8 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) {
grpc_channel_destroy(internal_channel);
}
-class ChannelzSubchannelTest : public ::testing::TestWithParam<size_t> {};
-
-TEST_P(ChannelzSubchannelTest, BasicTest) {
- grpc_core::ExecCtx exec_ctx;
- RefCountedPtr<SubchannelNode> channelz_subchannel =
- MakeRefCounted<SubchannelNode>(GetParam());
- channelz_subchannel->RecordCallStarted();
- channelz_subchannel->RecordCallFailed();
- channelz_subchannel->RecordCallSucceeded();
- ValidateSubchannel(channelz_subchannel.get(), {1, 1, 1});
- channelz_subchannel->RecordCallStarted();
- channelz_subchannel->RecordCallFailed();
- channelz_subchannel->RecordCallSucceeded();
- channelz_subchannel->RecordCallStarted();
- channelz_subchannel->RecordCallFailed();
- channelz_subchannel->RecordCallSucceeded();
- ValidateSubchannel(channelz_subchannel.get(), {3, 3, 3});
-}
-
INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest,
::testing::Values(0, 1, 2, 6, 10, 15));
-INSTANTIATE_TEST_CASE_P(ChannelzSubchannelTestSweep, ChannelzSubchannelTest,
- ::testing::Values(0, 1, 10, 15));
} // namespace testing
} // namespace channelz