raft: add fmt::formatter for raft tracker types

before this change, we rely on the default-generated fmt::formatter
created from operator<<, but fmt v10 dropped the default-generated
formatter.

in this change, we define formatters for

* raft::election_tracker
* raft::votes
* raft::vote_result

and drop their operator<<:s.

Refs #13245

Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>

Closes scylladb/scylladb#17670
This commit is contained in:
Kefu Chai
2024-03-07 14:10:42 +08:00
committed by Botond Dénes
parent 44bbf2e57b
commit 079d70145e
3 changed files with 58 additions and 36 deletions

View File

@@ -256,36 +256,38 @@ vote_result votes::tally_votes() const {
return _current.tally_votes();
}
std::ostream& operator<<(std::ostream& os, const election_tracker& v) {
os << "responded: " << v._responded.size() << ", ";
os << "granted: " << v._granted;
return os;
}
std::ostream& operator<<(std::ostream& os, const votes& v) {
os << "current: " << v._current << std::endl;
if (v._previous) {
os << "previous: " << v._previous.value() << std::endl;
}
return os;
}
std::ostream& operator<<(std::ostream& os, const vote_result& v) {
static const char *n;
switch (v) {
case vote_result::UNKNOWN:
n = "UNKNOWN";
break;
case vote_result::WON:
n = "WON";
break;
case vote_result::LOST:
n = "LOST";
break;
}
os << n;
return os;
}
} // end of namespace raft
auto fmt::formatter<raft::election_tracker>::format(const raft::election_tracker& v, fmt::format_context& ctx) const
-> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "responded: {}, granted: {}",
v._responded.size(), v._granted);
}
auto fmt::formatter<raft::votes>::format(const raft::votes& v, fmt::format_context& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = fmt::format_to(out, "current: {}\n", v._current);
if (v._previous) {
out = fmt::format_to(out, "previous: {}\n", v._previous.value());
}
return out;
}
auto fmt::formatter<raft::vote_result>::format(const raft::vote_result& v, fmt::format_context& ctx) const
-> decltype(ctx.out()) {
std::string_view name;
using enum raft::vote_result;
switch (v) {
case UNKNOWN:
name = "UNKNOWN";
break;
case WON:
name = "WON";
break;
case LOST:
name = "LOST";
break;
}
return formatter<std::string_view>::format(name, ctx);
}

View File

@@ -8,6 +8,7 @@
#pragma once
#include <seastar/core/condition-variable.hh>
#include <fmt/core.h>
#include "raft.hh"
namespace raft {
@@ -145,8 +146,6 @@ enum class vote_result {
LOST,
};
std::ostream& operator<<(std::ostream& os, const vote_result& v);
// State of election in a single quorum
class election_tracker {
// All eligible voters
@@ -182,7 +181,7 @@ public:
auto unknown = _suffrage.size() - _responded.size();
return _granted + unknown >= quorum ? vote_result::UNKNOWN : vote_result::LOST;
}
friend std::ostream& operator<<(std::ostream& os, const election_tracker& v);
friend fmt::formatter<election_tracker>;
};
// Candidate's state specific to election
@@ -202,8 +201,19 @@ public:
void register_vote(server_id from, bool granted);
vote_result tally_votes() const;
friend std::ostream& operator<<(std::ostream& os, const votes& v);
friend fmt::formatter<votes>;
};
} // namespace raft
template <> struct fmt::formatter<raft::election_tracker> : fmt::formatter<std::string_view> {
auto format(const raft::election_tracker& v, fmt::format_context& ctx) const -> decltype(ctx.out());
};
template <> struct fmt::formatter<raft::votes> : fmt::formatter<std::string_view> {
auto format(const raft::votes& v, fmt::format_context& ctx) const -> decltype(ctx.out());
};
template <> struct fmt::formatter<raft::vote_result> : fmt::formatter<std::string_view> {
auto format(const raft::vote_result& v, fmt::format_context& ctx) const -> decltype(ctx.out());
};

View File

@@ -8,10 +8,20 @@
#define BOOST_TEST_MODULE raft
#include "raft/tracker.hh"
#include "test/raft/helpers.hh"
using namespace raft;
namespace raft {
std::ostream& boost_test_print_type(std::ostream& os, const vote_result& v) {
fmt::print(os, "{}", v);
return os;
}
}
BOOST_AUTO_TEST_CASE(test_votes) {
auto id1 = id();