|
|
|
@ -117,36 +117,46 @@ void ChannelzRegistry::InternalUnregister(intptr_t uuid) { |
|
|
|
|
MaybePerformCompactionLocked(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) { |
|
|
|
|
RefCountedPtr<BaseNode> ChannelzRegistry::InternalGet(intptr_t uuid) { |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
if (uuid < 1 || uuid > uuid_generator_) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
int idx = FindByUuidLocked(uuid, true); |
|
|
|
|
return idx < 0 ? nullptr : entities_[idx]; |
|
|
|
|
if (idx < 0 || entities_[idx] == nullptr) return nullptr; |
|
|
|
|
// Found node. Return only if its refcount is not zero (i.e., when we
|
|
|
|
|
// know that there is no other thread about to destroy it).
|
|
|
|
|
if (!entities_[idx]->RefIfNonZero()) return nullptr; |
|
|
|
|
return RefCountedPtr<BaseNode>(entities_[idx]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); |
|
|
|
|
grpc_json* json = top_level_json; |
|
|
|
|
grpc_json* json_iterator = nullptr; |
|
|
|
|
InlinedVector<BaseNode*, 10> top_level_channels; |
|
|
|
|
bool reached_pagination_limit = false; |
|
|
|
|
int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); |
|
|
|
|
for (size_t i = start_idx; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr && |
|
|
|
|
entities_[i]->type() == |
|
|
|
|
grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && |
|
|
|
|
entities_[i]->uuid() >= start_channel_id) { |
|
|
|
|
// check if we are over pagination limit to determine if we need to set
|
|
|
|
|
// the "end" element. If we don't go through this block, we know that
|
|
|
|
|
// when the loop terminates, we have <= to kPaginationLimit.
|
|
|
|
|
if (top_level_channels.size() == kPaginationLimit) { |
|
|
|
|
reached_pagination_limit = true; |
|
|
|
|
break; |
|
|
|
|
InlinedVector<RefCountedPtr<BaseNode>, 10> top_level_channels; |
|
|
|
|
RefCountedPtr<BaseNode> node_after_pagination_limit; |
|
|
|
|
{ |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
const int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); |
|
|
|
|
for (size_t i = start_idx; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr && |
|
|
|
|
entities_[i]->type() == |
|
|
|
|
grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && |
|
|
|
|
entities_[i]->uuid() >= start_channel_id && |
|
|
|
|
entities_[i]->RefIfNonZero()) { |
|
|
|
|
// Check if we are over pagination limit to determine if we need to set
|
|
|
|
|
// the "end" element. If we don't go through this block, we know that
|
|
|
|
|
// when the loop terminates, we have <= to kPaginationLimit.
|
|
|
|
|
// Note that because we have already increased this node's
|
|
|
|
|
// refcount, we need to decrease it, but we can't unref while
|
|
|
|
|
// holding the lock, because this may lead to a deadlock.
|
|
|
|
|
if (top_level_channels.size() == kPaginationLimit) { |
|
|
|
|
node_after_pagination_limit.reset(entities_[i]); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
top_level_channels.emplace_back(entities_[i]); |
|
|
|
|
} |
|
|
|
|
top_level_channels.push_back(entities_[i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!top_level_channels.empty()) { |
|
|
|
@ -159,7 +169,7 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { |
|
|
|
|
grpc_json_link_child(array_parent, channel_json, json_iterator); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!reached_pagination_limit) { |
|
|
|
|
if (node_after_pagination_limit == nullptr) { |
|
|
|
|
grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, |
|
|
|
|
false); |
|
|
|
|
} |
|
|
|
@ -169,26 +179,32 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); |
|
|
|
|
grpc_json* json = top_level_json; |
|
|
|
|
grpc_json* json_iterator = nullptr; |
|
|
|
|
InlinedVector<BaseNode*, 10> servers; |
|
|
|
|
bool reached_pagination_limit = false; |
|
|
|
|
int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); |
|
|
|
|
for (size_t i = start_idx; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr && |
|
|
|
|
entities_[i]->type() == |
|
|
|
|
grpc_core::channelz::BaseNode::EntityType::kServer && |
|
|
|
|
entities_[i]->uuid() >= start_server_id) { |
|
|
|
|
// check if we are over pagination limit to determine if we need to set
|
|
|
|
|
// the "end" element. If we don't go through this block, we know that
|
|
|
|
|
// when the loop terminates, we have <= to kPaginationLimit.
|
|
|
|
|
if (servers.size() == kPaginationLimit) { |
|
|
|
|
reached_pagination_limit = true; |
|
|
|
|
break; |
|
|
|
|
InlinedVector<RefCountedPtr<BaseNode>, 10> servers; |
|
|
|
|
RefCountedPtr<BaseNode> node_after_pagination_limit; |
|
|
|
|
{ |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
const int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); |
|
|
|
|
for (size_t i = start_idx; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr && |
|
|
|
|
entities_[i]->type() == |
|
|
|
|
grpc_core::channelz::BaseNode::EntityType::kServer && |
|
|
|
|
entities_[i]->uuid() >= start_server_id && |
|
|
|
|
entities_[i]->RefIfNonZero()) { |
|
|
|
|
// Check if we are over pagination limit to determine if we need to set
|
|
|
|
|
// the "end" element. If we don't go through this block, we know that
|
|
|
|
|
// when the loop terminates, we have <= to kPaginationLimit.
|
|
|
|
|
// Note that because we have already increased this node's
|
|
|
|
|
// refcount, we need to decrease it, but we can't unref while
|
|
|
|
|
// holding the lock, because this may lead to a deadlock.
|
|
|
|
|
if (servers.size() == kPaginationLimit) { |
|
|
|
|
node_after_pagination_limit.reset(entities_[i]); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
servers.emplace_back(entities_[i]); |
|
|
|
|
} |
|
|
|
|
servers.push_back(entities_[i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!servers.empty()) { |
|
|
|
@ -201,7 +217,7 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { |
|
|
|
|
grpc_json_link_child(array_parent, server_json, json_iterator); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!reached_pagination_limit) { |
|
|
|
|
if (node_after_pagination_limit == nullptr) { |
|
|
|
|
grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, |
|
|
|
|
false); |
|
|
|
|
} |
|
|
|
@ -211,14 +227,20 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ChannelzRegistry::InternalLogAllEntities() { |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
for (size_t i = 0; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr) { |
|
|
|
|
char* json = entities_[i]->RenderJsonString(); |
|
|
|
|
gpr_log(GPR_INFO, "%s", json); |
|
|
|
|
gpr_free(json); |
|
|
|
|
InlinedVector<RefCountedPtr<BaseNode>, 10> nodes; |
|
|
|
|
{ |
|
|
|
|
MutexLock lock(&mu_); |
|
|
|
|
for (size_t i = 0; i < entities_.size(); ++i) { |
|
|
|
|
if (entities_[i] != nullptr && entities_[i]->RefIfNonZero()) { |
|
|
|
|
nodes.emplace_back(entities_[i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (size_t i = 0; i < nodes.size(); ++i) { |
|
|
|
|
char* json = nodes[i]->RenderJsonString(); |
|
|
|
|
gpr_log(GPR_INFO, "%s", json); |
|
|
|
|
gpr_free(json); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace channelz
|
|
|
|
@ -234,7 +256,7 @@ char* grpc_channelz_get_servers(intptr_t start_server_id) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* grpc_channelz_get_server(intptr_t server_id) { |
|
|
|
|
grpc_core::channelz::BaseNode* server_node = |
|
|
|
|
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> server_node = |
|
|
|
|
grpc_core::channelz::ChannelzRegistry::Get(server_id); |
|
|
|
|
if (server_node == nullptr || |
|
|
|
|
server_node->type() != |
|
|
|
@ -254,7 +276,7 @@ char* grpc_channelz_get_server(intptr_t server_id) { |
|
|
|
|
char* grpc_channelz_get_server_sockets(intptr_t server_id, |
|
|
|
|
intptr_t start_socket_id, |
|
|
|
|
intptr_t max_results) { |
|
|
|
|
grpc_core::channelz::BaseNode* base_node = |
|
|
|
|
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> base_node = |
|
|
|
|
grpc_core::channelz::ChannelzRegistry::Get(server_id); |
|
|
|
|
if (base_node == nullptr || |
|
|
|
|
base_node->type() != grpc_core::channelz::BaseNode::EntityType::kServer) { |
|
|
|
@ -263,12 +285,12 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, |
|
|
|
|
// This cast is ok since we have just checked to make sure base_node is
|
|
|
|
|
// actually a server node
|
|
|
|
|
grpc_core::channelz::ServerNode* server_node = |
|
|
|
|
static_cast<grpc_core::channelz::ServerNode*>(base_node); |
|
|
|
|
static_cast<grpc_core::channelz::ServerNode*>(base_node.get()); |
|
|
|
|
return server_node->RenderServerSockets(start_socket_id, max_results); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* grpc_channelz_get_channel(intptr_t channel_id) { |
|
|
|
|
grpc_core::channelz::BaseNode* channel_node = |
|
|
|
|
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> channel_node = |
|
|
|
|
grpc_core::channelz::ChannelzRegistry::Get(channel_id); |
|
|
|
|
if (channel_node == nullptr || |
|
|
|
|
(channel_node->type() != |
|
|
|
@ -288,7 +310,7 @@ char* grpc_channelz_get_channel(intptr_t channel_id) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { |
|
|
|
|
grpc_core::channelz::BaseNode* subchannel_node = |
|
|
|
|
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> subchannel_node = |
|
|
|
|
grpc_core::channelz::ChannelzRegistry::Get(subchannel_id); |
|
|
|
|
if (subchannel_node == nullptr || |
|
|
|
|
subchannel_node->type() != |
|
|
|
@ -306,7 +328,7 @@ char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* grpc_channelz_get_socket(intptr_t socket_id) { |
|
|
|
|
grpc_core::channelz::BaseNode* socket_node = |
|
|
|
|
grpc_core::RefCountedPtr<grpc_core::channelz::BaseNode> socket_node = |
|
|
|
|
grpc_core::channelz::ChannelzRegistry::Get(socket_id); |
|
|
|
|
if (socket_node == nullptr || |
|
|
|
|
socket_node->type() != |
|
|
|
|