8000 RAFT read bug · AthonyLi/arangodb@4f98c4d · GitHub
[go: up one dir, main page]

Skip to content

Commit 4f98c4d

Browse files
committed
RAFT read bug
1 parent 149ef4a commit 4f98c4d

File tree

3 files changed

+36
-21
lines changed

3 files changed

+36
-21
lines changed

arangod/Agency/Agent.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -484,22 +484,22 @@ read_ret_t Agent::read(query_t const& query) {
484484
// Only leader else redirect
485485
if (!_constituent.leading()) {
486486
return read_ret_t(false, _constituent.leaderID());
487-
}
488-
489-
// Still leading?
490-
size_t good = 0;
491-
for (auto const& i : _lastAcked) {
492-
std::chrono::duration<double> m =
493-
std::chrono::system_clock::now() - i.second;
494-
if(0.9*_config.minPing() > m.count()) {
495-
++good;
487+
} else {
488+
// Still leading?
489+
size_t good = 0;
490+
for (auto const& i : _lastAcked) {
491+
std::chrono::duration<double> m =
492+
std::chrono::system_clock::now() - i.second;
493+
if(0.9*_config.minPing() > m.count()) {
494+
++good;
495+
}
496+
}
497+
if (good < size() / 2) {
498+
_constituent.candidate();
499+
return read_ret_t(false, NO_LEADER);
496500
}
497501
}
498-
499-
if (good < size() / 2) {
500-
_constituent.candidate();
501-
}
502-
502+
503503
// Retrieve data from readDB
504504
auto result = std::make_shared<arangodb::velocypack::Builder>();
505505
std::vector<bool> success = _readDB.read(query, result);

arangod/Agency/Constituent.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ void Constituent::lead(std::map<std::string, bool> const& votes) {
214214
void Constituent::candidate() {
215215

216216
MUTEX_LOCKER(guard, _castLock);
217+
218+
_leaderID = NO_LEADER;
217219

218220
if (_role != CANDIDATE)
219221
LOG_TOPIC(DEBUG, Logger::AGENCY)

arangod/Agency/RestAgencyHandler.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,8 @@ RestHandler::status RestAgencyHandler::handleWrite() {
140140
}
141141

142142
auto s = std::chrono::system_clock::now(); // Leadership established?
143-
std::chrono::seconds timeout(1);
143+
std::chrono::duration<double> timeout(_agent->config().minPing());
144144
while(_agent->size() > 1 && _agent->leaderID() == "") {
145-
std::this_thread::sleep_for(duration_t(100));
146145
if ((std::chrono::system_clock::now()-s) > timeout) {
147146
Builder body;
148147
body.openObject();
@@ -153,12 +152,12 @@ RestHandler::status RestAgencyHandler::handleWrite() {
153152
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
154153
return status::DONE;
155154
}
155+
std::this_thread::sleep_for(duration_t(100));
156156
}
157157

158158
write_ret_t ret = _agent->write(query);
159159

160160
if (ret.accepted) { // We're leading and handling the request
161-
162161
bool found;
163162
std::string call_mode = _request->header("x-arangodb-agency-mode", found);
164163
if (!found) {
@@ -227,9 +226,8 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
227226
}
228227

229228
auto s = std::chrono::system_clock::now(); // Leadership established?
230-
std::chrono::seconds timeout(1);
231-
while(_agent->size() > 1 && _agent->leaderID() == "") {
232-
std::this_thread::sleep_for(duration_t(100));
229+
std::chrono::duration<double> timeout(_agent->config().minPing());
230+
while(_agent->size() > 1 && _agent->leaderID() == NO_LEADER) {
233231
if ((std::chrono::system_clock::now()-s) > timeout) {
234232
Builder body;
235233
body.openObject();
@@ -240,6 +238,7 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
240238
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
241239
return status::DONE;
242240
}
241+
std::this_thread::sleep_for(duration_t(100));
243242
}
244243

245244
read_ret_t ret = _agent->read(query);
@@ -252,7 +251,20 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
252251
generateResult(GeneralResponse::ResponseCode::OK, ret.result->slice());
253252
}
254253
} else { // Redirect to leader
255-
redirectRequest(ret.redirect);
254+
if (_agent->leaderID() == NO_LEADER) {
255+
256+
Builder body;
257+
body.openObject();
258+
body.add("message", VPackValue("No leader"));
259+
body.close();
260+
generateResult(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE,
261+
body.slice());
262+
LOG_TOPIC(ERR, Logger::AGENCY) << "We don't know who the leader is";
263+
return status::DONE;
264+
265+
} else {
266+
redirectRequest(ret.redirect);
267+
}
256268
return status::DONE;
257269
}
258270
} else {
@@ -263,6 +275,7 @@ inline RestHandler::status RestAgencyHandler::handleRead() {
263275
}
264276

265277
RestHandler::status RestAgencyHandler::handleConfig() {
278+
266279
Builder body;
267280
body.add(VPackValue(VPackValueType::Object));
268281
body.add("term", Value(_agent->term()));

0 commit comments

Comments
 (0)
0