topology: Add printer wrapper for node* and formatter for it
Currently to print node information there's a debug_format(node*) helper function that returns back an sstring object. Here's the formatter that's more flexible and convenient, and a node_printer wrapper, since formatters cannot format non-void pointers. Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
@@ -16,6 +16,24 @@
|
||||
#include "locator/production_snitch_base.hh"
|
||||
#include "utils/stall_free.hh"
|
||||
|
||||
struct node_printer {
|
||||
const locator::node* v;
|
||||
node_printer(const locator::node* n) noexcept : v(n) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct fmt::formatter<node_printer> {
|
||||
constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
|
||||
auto format(const node_printer& np, fmt::format_context& ctx) const {
|
||||
const locator::node* node = np.v;
|
||||
auto out = fmt::format_to(ctx.out(), "node={}", fmt::ptr(node));
|
||||
if (node) {
|
||||
out = fmt::format_to(out, " {:v}", *node);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
namespace locator {
|
||||
|
||||
static logging::logger tlogger("topology");
|
||||
@@ -124,14 +142,6 @@ future<topology> topology::clone_gently() const {
|
||||
co_return ret;
|
||||
}
|
||||
|
||||
std::string topology::debug_format(const node* node) {
|
||||
if (!node) {
|
||||
return format("node={}", fmt::ptr(node));
|
||||
}
|
||||
return format("node={} idx={} host_id={} endpoint={} dc={} rack={} state={} shards={} this_node={}", fmt::ptr(node),
|
||||
node->idx(), node->host_id(), node->endpoint(), node->dc_rack().dc, node->dc_rack().rack, node::to_string(node->get_state()), node->get_shard_count(), bool(node->is_this_node()));
|
||||
}
|
||||
|
||||
const node* topology::add_node(host_id id, const inet_address& ep, const endpoint_dc_rack& dr, node::state state, shard_id shard_count) {
|
||||
if (dr.dc.empty() || dr.rack.empty()) {
|
||||
on_internal_error(tlogger, "Node must have valid dc and rack");
|
||||
@@ -154,13 +164,13 @@ const node* topology::add_node(node_holder nptr) {
|
||||
|
||||
if (nptr->topology() != this) {
|
||||
if (nptr->topology()) {
|
||||
on_fatal_internal_error(tlogger, format("topology[{}]: {} belongs to different topology={}", fmt::ptr(this), debug_format(node), fmt::ptr(node->topology())));
|
||||
on_fatal_internal_error(tlogger, format("topology[{}]: {} belongs to different topology={}", fmt::ptr(this), node_printer(node), fmt::ptr(node->topology())));
|
||||
}
|
||||
nptr->set_topology(this);
|
||||
}
|
||||
|
||||
if (node->idx() > 0) {
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: has assigned idx", fmt::ptr(this), debug_format(node)));
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: has assigned idx", fmt::ptr(this), nptr));
|
||||
}
|
||||
|
||||
// Note that _nodes contains also the this_node()
|
||||
@@ -170,7 +180,7 @@ const node* topology::add_node(node_holder nptr) {
|
||||
try {
|
||||
if (is_configured_this_node(*node)) {
|
||||
if (_this_node) {
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: local node already mapped to {}", fmt::ptr(this), debug_format(node), debug_format(this_node())));
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: local node already mapped to {}", fmt::ptr(this), node_printer(node), node_printer(this_node())));
|
||||
}
|
||||
locator::node& n = *_nodes.back();
|
||||
n._is_this_node = node::this_node::yes;
|
||||
@@ -180,7 +190,7 @@ const node* topology::add_node(node_holder nptr) {
|
||||
}
|
||||
|
||||
if (tlogger.is_enabled(log_level::debug)) {
|
||||
tlogger.debug("topology[{}]: add_node: {}, at {}", fmt::ptr(this), debug_format(node), current_backtrace());
|
||||
tlogger.debug("topology[{}]: add_node: {}, at {}", fmt::ptr(this), nptr, current_backtrace());
|
||||
}
|
||||
|
||||
index_node(node);
|
||||
@@ -193,7 +203,7 @@ const node* topology::add_node(node_holder nptr) {
|
||||
|
||||
const node* topology::update_node(node* node, std::optional<host_id> opt_id, std::optional<inet_address> opt_ep, std::optional<endpoint_dc_rack> opt_dr, std::optional<node::state> opt_st, std::optional<shard_id> opt_shard_count) {
|
||||
if (tlogger.is_enabled(log_level::debug)) {
|
||||
tlogger.debug("topology[{}]: update_node: {}: to: host_id={} endpoint={} dc={} rack={} state={}, at {}", fmt::ptr(this), debug_format(node),
|
||||
tlogger.debug("topology[{}]: update_node: {}: to: host_id={} endpoint={} dc={} rack={} state={}, at {}", fmt::ptr(this), node_printer(node),
|
||||
opt_id ? format("{}", *opt_id) : "unchanged",
|
||||
opt_ep ? format("{}", *opt_ep) : "unchanged",
|
||||
opt_dr ? format("{}", opt_dr->dc) : "unchanged",
|
||||
@@ -207,13 +217,13 @@ const node* topology::update_node(node* node, std::optional<host_id> opt_id, std
|
||||
if (opt_id) {
|
||||
if (*opt_id != node->host_id()) {
|
||||
if (!*opt_id) {
|
||||
on_internal_error(tlogger, format("Updating node host_id to null is disallowed: {}: new host_id={}", debug_format(node), *opt_id));
|
||||
on_internal_error(tlogger, format("Updating node host_id to null is disallowed: {}: new host_id={}", node_printer(node), *opt_id));
|
||||
}
|
||||
if (node->is_this_node() && node->host_id()) {
|
||||
on_internal_error(tlogger, format("This node host_id is already set: {}: new host_id={}", debug_format(node), *opt_id));
|
||||
on_internal_error(tlogger, format("This node host_id is already set: {}: new host_id={}", node_printer(node), *opt_id));
|
||||
}
|
||||
if (_nodes_by_host_id.contains(*opt_id)) {
|
||||
on_internal_error(tlogger, format("Cannot update node host_id: {}: new host_id already exists: {}", debug_format(node), debug_format(_nodes_by_host_id[*opt_id])));
|
||||
on_internal_error(tlogger, format("Cannot update node host_id: {}: new host_id already exists: {}", node_printer(node), node_printer(_nodes_by_host_id[*opt_id])));
|
||||
}
|
||||
changed = true;
|
||||
} else {
|
||||
@@ -223,7 +233,7 @@ const node* topology::update_node(node* node, std::optional<host_id> opt_id, std
|
||||
if (opt_ep) {
|
||||
if (*opt_ep != node->endpoint()) {
|
||||
if (*opt_ep == inet_address{}) {
|
||||
on_internal_error(tlogger, format("Updating node endpoint to null is disallowed: {}: new endpoint={}", debug_format(node), *opt_ep));
|
||||
on_internal_error(tlogger, format("Updating node endpoint to null is disallowed: {}: new endpoint={}", node_printer(node), *opt_ep));
|
||||
}
|
||||
changed = true;
|
||||
} else {
|
||||
@@ -282,7 +292,7 @@ const node* topology::update_node(node* node, std::optional<host_id> opt_id, std
|
||||
|
||||
bool topology::remove_node(host_id id) {
|
||||
auto node = find_node(id);
|
||||
tlogger.debug("topology[{}]: remove_node: host_id={}: {}", fmt::ptr(this), id, debug_format(node));
|
||||
tlogger.debug("topology[{}]: remove_node: host_id={}: {}", fmt::ptr(this), id, node_printer(node));
|
||||
if (node) {
|
||||
remove_node(node);
|
||||
return true;
|
||||
@@ -296,11 +306,11 @@ void topology::remove_node(const node* node) {
|
||||
|
||||
void topology::index_node(const node* node) {
|
||||
if (tlogger.is_enabled(log_level::trace)) {
|
||||
tlogger.trace("topology[{}]: index_node: {}, at {}", fmt::ptr(this), debug_format(node), current_backtrace());
|
||||
tlogger.trace("topology[{}]: index_node: {}, at {}", fmt::ptr(this), node_printer(node), current_backtrace());
|
||||
}
|
||||
|
||||
if (node->idx() < 0) {
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: must already have a valid idx", fmt::ptr(this), debug_format(node)));
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: must already have a valid idx", fmt::ptr(this), node_printer(node)));
|
||||
}
|
||||
|
||||
// FIXME: for now we allow adding nodes with null host_id, for the following cases:
|
||||
@@ -310,7 +320,7 @@ void topology::index_node(const node* node) {
|
||||
if (node->host_id()) {
|
||||
auto [nit, inserted_host_id] = _nodes_by_host_id.emplace(node->host_id(), node);
|
||||
if (!inserted_host_id) {
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: node already exists", fmt::ptr(this), debug_format(node)));
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: node already exists", fmt::ptr(this), node_printer(node)));
|
||||
}
|
||||
}
|
||||
if (node->endpoint() != inet_address{}) {
|
||||
@@ -327,7 +337,7 @@ void topology::index_node(const node* node) {
|
||||
if (node->host_id()) {
|
||||
_nodes_by_host_id.erase(node->host_id());
|
||||
}
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: node endpoint already mapped to {}", fmt::ptr(this), debug_format(node), debug_format(eit->second)));
|
||||
on_internal_error(tlogger, format("topology[{}]: {}: node endpoint already mapped to {}", fmt::ptr(this), node_printer(node), node_printer(eit->second)));
|
||||
}
|
||||
}
|
||||
if (node->get_state() != node::state::left) {
|
||||
@@ -351,7 +361,7 @@ void topology::index_node(const node* node) {
|
||||
|
||||
void topology::unindex_node(const node* node) {
|
||||
if (tlogger.is_enabled(log_level::trace)) {
|
||||
tlogger.trace("topology[{}]: unindex_node: {}, at {}", fmt::ptr(this), debug_format(node), current_backtrace());
|
||||
tlogger.trace("topology[{}]: unindex_node: {}, at {}", fmt::ptr(this), node_printer(node), current_backtrace());
|
||||
}
|
||||
|
||||
const auto& dc = node->dc_rack().dc;
|
||||
@@ -397,7 +407,7 @@ void topology::unindex_node(const node* node) {
|
||||
|
||||
node_holder topology::pop_node(const node* node) {
|
||||
if (tlogger.is_enabled(log_level::trace)) {
|
||||
tlogger.trace("topology[{}]: pop_node: {}, at {}", fmt::ptr(this), debug_format(node), current_backtrace());
|
||||
tlogger.trace("topology[{}]: pop_node: {}, at {}", fmt::ptr(this), node_printer(node), current_backtrace());
|
||||
}
|
||||
|
||||
unindex_node(node);
|
||||
@@ -473,7 +483,7 @@ const node* topology::add_or_update_endpoint(host_id id, std::optional<inet_addr
|
||||
bool topology::remove_endpoint(locator::host_id host_id)
|
||||
{
|
||||
auto node = find_node(host_id);
|
||||
tlogger.debug("topology[{}]: remove_endpoint: host_id={}: {}", fmt::ptr(this), host_id, debug_format(node));
|
||||
tlogger.debug("topology[{}]: remove_endpoint: host_id={}: {}", fmt::ptr(this), host_id, node_printer(node));
|
||||
if (node) {
|
||||
remove_node(node);
|
||||
return true;
|
||||
@@ -483,13 +493,13 @@ bool topology::remove_endpoint(locator::host_id host_id)
|
||||
|
||||
bool topology::has_node(host_id id) const noexcept {
|
||||
auto node = find_node(id);
|
||||
tlogger.trace("topology[{}]: has_node: host_id={}: {}", fmt::ptr(this), id, debug_format(node));
|
||||
tlogger.trace("topology[{}]: has_node: host_id={}: {}", fmt::ptr(this), id, node_printer(node));
|
||||
return bool(node);
|
||||
}
|
||||
|
||||
bool topology::has_node(inet_address ep) const noexcept {
|
||||
auto node = find_node(ep);
|
||||
tlogger.trace("topology[{}]: has_node: endpoint={}: node={}", fmt::ptr(this), ep, debug_format(node));
|
||||
tlogger.trace("topology[{}]: has_node: endpoint={}: node={}", fmt::ptr(this), ep, node_printer(node));
|
||||
return bool(node);
|
||||
}
|
||||
|
||||
@@ -564,7 +574,7 @@ std::ostream& operator<<(std::ostream& out, const locator::topology& t) {
|
||||
<< ", rack: " << t._cfg.local_dc_rack.rack
|
||||
<< ", nodes:\n";
|
||||
for (auto&& node : t._nodes) {
|
||||
out << " " << locator::topology::debug_format(&*node) << "\n";
|
||||
out << " " << fmt::format("{}", node_printer(node.get())) << "\n";
|
||||
}
|
||||
return out << "}";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user