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