mirror of https://gitee.com/bigwinds/arangodb
fixed seldom race in election pulled back from 3.0
This commit is contained in:
parent
414e4ac714
commit
e4556bb766
|
@ -77,13 +77,13 @@ Constituent::Constituent()
|
|||
_vocbase(nullptr),
|
||||
_queryRegistry(nullptr),
|
||||
_term(0),
|
||||
_cast(false),
|
||||
_leaderID((std::numeric_limits<arangodb::consensus::id_t>::max)()),
|
||||
_id(0),
|
||||
_role(FOLLOWER),
|
||||
_agent(nullptr),
|
||||
_votedFor((std::numeric_limits<arangodb::consensus::id_t>::max)()),
|
||||
_notifier(nullptr) {
|
||||
}
|
||||
_notifier(nullptr) {}
|
||||
|
||||
|
||||
/// Shutdown if not already
|
||||
|
@ -131,7 +131,8 @@ void Constituent::term(term_t t) {
|
|||
|
||||
if (tmp != t) {
|
||||
|
||||
LOG_TOPIC(INFO, Logger::AGENCY) << roleStr[_role] << " term " << t;
|
||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||
<< _id << ": " << roleStr[_role] << " term " << t;
|
||||
|
||||
Builder body;
|
||||
body.add(VPackValue(VPackValueType::Object));
|
||||
|
@ -180,7 +181,7 @@ void Constituent::follow(term_t t) {
|
|||
|
||||
if (_role != FOLLOWER) {
|
||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||
<< "Role change: Converting to follower in term " << t;
|
||||
<< _id << ": Converting to follower in term " << t;
|
||||
}
|
||||
|
||||
_term = t;
|
||||
|
@ -190,13 +191,19 @@ void Constituent::follow(term_t t) {
|
|||
|
||||
|
||||
/// Become leader
|
||||
void Constituent::lead() {
|
||||
void Constituent::lead(std::vector<bool> const& votes) {
|
||||
|
||||
MUTEX_LOCKER(guard, _castLock);
|
||||
|
||||
if (_role != LEADER) {
|
||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||
<< "Role change: Converted to leader in term " << _term;
|
||||
std::stringstream ss;
|
||||
ss << _id << ": Converted to leader in term " << _term << " with votes (";
|
||||
for (auto const& vote : votes) {
|
||||
ss << vote;
|
||||
}
|
||||
ss << ")";
|
||||
|
||||
LOG_TOPIC(INFO, Logger::AGENCY) << ss.str();
|
||||
_agent->lead(); // We need to rebuild spear_head and read_db;
|
||||
}
|
||||
|
||||
|
@ -213,7 +220,7 @@ void Constituent::candidate() {
|
|||
|
||||
if (_role != CANDIDATE)
|
||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||
<< "Role change: Converted to candidate in term " << _term;
|
||||
<< _id << ": Converted to candidate in term " << _term;
|
||||
|
||||
_role = CANDIDATE;
|
||||
|
||||
|
@ -300,18 +307,23 @@ void Constituent::notifyAll() {
|
|||
/// @brief Vote
|
||||
bool Constituent::vote(term_t term, arangodb::consensus::id_t id,
|
||||
index_t prevLogIndex, term_t prevLogTerm) {
|
||||
|
||||
term_t t = 0;
|
||||
arangodb::consensus::id_t lid = 0;
|
||||
bool cast = false;
|
||||
|
||||
{
|
||||
MUTEX_LOCKER(guard, _castLock);
|
||||
t = _term;
|
||||
lid = _leaderID;
|
||||
cast = _cast;
|
||||
_cast = true;
|
||||
}
|
||||
if (term > t || (t == term && lid == id)) {
|
||||
|
||||
if (term > t || (t == term && lid == id && !cast)) {
|
||||
this->term(term);
|
||||
{
|
||||
MUTEX_LOCKER(guard, _castLock);
|
||||
_cast = true; // Note that I voted this time around.
|
||||
_votedFor = id; // The guy I voted for I assume leader.
|
||||
_leaderID = id;
|
||||
}
|
||||
|
@ -323,9 +335,10 @@ bool Constituent::vote(term_t term, arangodb::consensus::id_t id,
|
|||
_cv.signal();
|
||||
}
|
||||
return true;
|
||||
} else { // Myself running or leading
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/// @brief Call to election
|
||||
|
@ -405,7 +418,7 @@ void Constituent::callElection() {
|
|||
|
||||
// Evaluate election results
|
||||
if (yea > size() / 2) {
|
||||
lead();
|
||||
lead(votes);
|
||||
} else {
|
||||
follow(_term);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ class Constituent : public arangodb::Thread {
|
|||
void candidate();
|
||||
|
||||
/// @brief Become leader
|
||||
void lead();
|
||||
void lead(std::vector<bool> const&);
|
||||
|
||||
/// @brief Call for vote (by leader or candidates after timeout)
|
||||
void callElection();
|
||||
|
|
Loading…
Reference in New Issue