1
0
Fork 0

RAFT read bug

This commit is contained in:
Kaveh Vahedipour 2016-09-01 09:18:44 +02:00
parent 149ef4ab8b
commit 4f98c4dd49
3 changed files with 36 additions and 21 deletions

View File

@ -484,22 +484,22 @@ read_ret_t Agent::read(query_t const& query) {
// Only leader else redirect
if (!_constituent.leading()) {
return read_ret_t(false, _constituent.leaderID());
}
// Still leading?
size_t good = 0;
for (auto const& i : _lastAcked) {
std::chrono::duration<double> m =
std::chrono::system_clock::now() - i.second;
if(0.9*_config.minPing() > m.count()) {
++good;
} else {
// Still leading?
size_t good = 0;
for (auto const& i : _lastAcked) {
std::chrono::duration<double> m =
std::chrono::system_clock::now() - i.second;
if(0.9*_config.minPing() > m.count()) {
++good;
}
}
if (good < size() / 2) {
_constituent.candidate();
return read_ret_t(false, NO_LEADER);
}
}
if (good < size() / 2) {
_constituent.candidate();
}
// Retrieve data from readDB
auto result = std::make_shared<arangodb::velocypack::Builder>();
std::vector<bool> success = _readDB.read(query, result);

View File

@ -214,6 +214,8 @@ void Constituent::lead(std::map<std::string, bool> const& votes) {
void Constituent::candidate() {
MUTEX_LOCKER(guard, _castLock);
_leaderID = NO_LEADER;
if (_role != CANDIDATE)
LOG_TOPIC(DEBUG, Logger::AGENCY)

View File

@ -140,9 +140,8 @@ RestHandler::status RestAgencyHandler::handleWrite() {
}
auto s = std::chrono::system_clock::now(); // Leadership established?
std::chrono::seconds timeout(1);
std::chrono::duration<double> timeout(_agent->config().minPing());
while(_agent->size() > 1 && _agent->leaderID() == "") {
std::this_thread::sleep_for(duration_t(100));
if ((std::chrono::system_clock::now()-s) > timeout) {
Builder body;
body.openObject();
@ -153,12 +152,12 @@ RestHandler::status RestAgencyHandler::handleWrite() {
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
return status::DONE;
}
std::this_thread::sleep_for(duration_t(100));
}
write_ret_t ret = _agent->write(query);
if (ret.accepted) { // We're leading and handling the request
bool found;
std::string call_mode = _request->header("x-arangodb-agency-mode", found);
if (!found) {
@ -227,9 +226,8 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
}
auto s = std::chrono::system_clock::now(); // Leadership established?
std::chrono::seconds timeout(1);
while(_agent->size() > 1 && _agent->leaderID() == "") {
std::this_thread::sleep_for(duration_t(100));
std::chrono::duration<double> timeout(_agent->config().minPing());
while(_agent->size() > 1 && _agent->leaderID() == NO_LEADER) {
if ((std::chrono::system_clock::now()-s) > timeout) {
Builder body;
body.openObject();
@ -240,6 +238,7 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
return status::DONE;
}
std::this_thread::sleep_for(duration_t(100));
}
read_ret_t ret = _agent->read(query);
@ -252,7 +251,20 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
generateResult(GeneralResponse::ResponseCode::OK, ret.result->slice());
}
} else { // Redirect to leader
redirectRequest(ret.redirect);
if (_agent->leaderID() == NO_LEADER) {
Builder body;
body.openObject();
body.add("message", VPackValue("No leader"));
body.close();
generateResult(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE,
body.slice());
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
return status::DONE;
} else {
redirectRequest(ret.redirect);
}
return status::DONE;
}
} else {
@ -263,6 +275,7 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
}
RestHandler::status RestAgencyHandler::handleConfig() {
Builder body;
body.add(VPackValue(VPackValueType::Object));
body.add("term", Value(_agent->term()));