mirror of https://gitee.com/bigwinds/arangodb
Fix performRequests?
This commit is contained in:
parent
3ee28ac333
commit
b993de3c42
|
@ -995,41 +995,63 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
|
||||||
std::unordered_map<OperationID, size_t> opIDtoIndex;
|
std::unordered_map<OperationID, size_t> opIDtoIndex;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (now <= endTime) {
|
while (true) {
|
||||||
|
now = TRI_microtime();
|
||||||
|
if (now > endTime) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (nrDone >= requests.size()) {
|
if (nrDone >= requests.size()) {
|
||||||
// All good, report
|
// All good, report
|
||||||
return nrGood;
|
return nrGood;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double actionNeeded = endTime;
|
||||||
|
|
||||||
// First send away what is due:
|
// First send away what is due:
|
||||||
for (size_t i = 0; i < requests.size(); i++) {
|
for (size_t i = 0; i < requests.size(); i++) {
|
||||||
if (!requests[i].done && now >= dueTime[i]) {
|
if (!requests[i].done) {
|
||||||
if (requests[i].headerFields.get() == nullptr) {
|
if (now >= dueTime[i]) {
|
||||||
requests[i].headerFields = std::make_unique<
|
if (requests[i].headerFields.get() == nullptr) {
|
||||||
std::unordered_map<std::string, std::string>>();
|
requests[i].headerFields = std::make_unique<
|
||||||
|
std::unordered_map<std::string, std::string>>();
|
||||||
|
}
|
||||||
|
LOG_TOPIC(TRACE, logTopic)
|
||||||
|
<< "ClusterComm::performRequests: sending request to "
|
||||||
|
<< requests[i].destination << ":" << requests[i].path
|
||||||
|
<< "body:" << requests[i].body;
|
||||||
|
|
||||||
|
dueTime[i] = endTime + 10;
|
||||||
|
double localTimeout = endTime - now;
|
||||||
|
OperationID opId = asyncRequest(
|
||||||
|
"", coordinatorTransactionID, requests[i].destination,
|
||||||
|
requests[i].requestType, requests[i].path, requests[i].body,
|
||||||
|
requests[i].headerFields, nullptr, localTimeout, false,
|
||||||
|
2.0);
|
||||||
|
|
||||||
|
opIDtoIndex.insert(std::make_pair(opId, i));
|
||||||
|
// It is possible that an error occurs right away, we will notice
|
||||||
|
// below after wait(), though, and retry in due course.
|
||||||
|
} else if (dueTime[i] < actionNeeded) {
|
||||||
|
actionNeeded = dueTime[i];
|
||||||
}
|
}
|
||||||
LOG_TOPIC(TRACE, logTopic)
|
|
||||||
<< "ClusterComm::performRequests: sending request to "
|
|
||||||
<< requests[i].destination << ":" << requests[i].path
|
|
||||||
<< "body:" << requests[i].body;
|
|
||||||
|
|
||||||
dueTime[i] = endTime + 10;
|
|
||||||
double localTimeout = endTime - now;
|
|
||||||
OperationID opId = asyncRequest(
|
|
||||||
"", coordinatorTransactionID, requests[i].destination,
|
|
||||||
requests[i].requestType, requests[i].path, requests[i].body,
|
|
||||||
requests[i].headerFields, nullptr, localTimeout, false,
|
|
||||||
2.0);
|
|
||||||
|
|
||||||
opIDtoIndex.insert(std::make_pair(opId, i));
|
|
||||||
// It is possible that an error occurs right away, we will notice
|
|
||||||
// below after wait(), though, and retry in due course.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto res = wait("", coordinatorTransactionID, 0, "", actionNeeded - now);
|
||||||
|
// wait could have taken some time, so we need to update now now
|
||||||
now = TRI_microtime();
|
now = TRI_microtime();
|
||||||
auto res =
|
// note that this is needed further below from here, so it is *not*
|
||||||
wait("", coordinatorTransactionID, 0, "", endTime - now);
|
// good enough to only update at the top of the loop!
|
||||||
|
|
||||||
|
if (res.status == CL_COMM_DROPPED) {
|
||||||
|
// this indicates that no request for this coordinatorTransactionID
|
||||||
|
// is in flight, this is possible, since we might have scheduled
|
||||||
|
// a retry later than now and simply wait till then
|
||||||
|
if (now < actionNeeded) {
|
||||||
|
usleep((actionNeeded - now) * 1000000);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = opIDtoIndex.find(res.operationID);
|
auto it = opIDtoIndex.find(res.operationID);
|
||||||
if (it == opIDtoIndex.end()) {
|
if (it == opIDtoIndex.end()) {
|
||||||
|
@ -1052,32 +1074,33 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
|
||||||
<< requests[index].path << " with return code "
|
<< requests[index].path << " with return code "
|
||||||
<< (int)res.answer_code;
|
<< (int)res.answer_code;
|
||||||
} else if (res.status == CL_COMM_BACKEND_UNAVAILABLE ||
|
} else if (res.status == CL_COMM_BACKEND_UNAVAILABLE ||
|
||||||
(res.status == CL_COMM_TIMEOUT && !res.sendWasComplete)) {
|
(res.status == CL_COMM_TIMEOUT && !res.sendWasComplete)) {
|
||||||
requests[index].result = res;
|
requests[index].result = res;
|
||||||
|
|
||||||
// In this case we will retry:
|
// In this case we will retry:
|
||||||
dueTime[index] =
|
double tryAgainAfter = now - startTime;
|
||||||
(std::min)(10.0, (std::max)(0.2, 2 * (now - startTime))) + now;
|
if (tryAgainAfter < 0.2) {
|
||||||
if (dueTime[index] >= endTime) {
|
tryAgainAfter = 0.2;
|
||||||
requests[index].done = true;
|
} else if (tryAgainAfter > 10.0) {
|
||||||
nrDone++;
|
tryAgainAfter = 10.0;
|
||||||
}
|
}
|
||||||
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
dueTime[index] = tryAgainAfter + now;
|
||||||
<< "got BACKEND_UNAVAILABLE or TIMEOUT from "
|
if (dueTime[index] >= endTime) {
|
||||||
<< requests[index].destination << ":" << requests[index].path;
|
|
||||||
} else { // a "proper error"
|
|
||||||
requests[index].result = res;
|
|
||||||
requests[index].done = true;
|
requests[index].done = true;
|
||||||
nrDone++;
|
nrDone++;
|
||||||
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
|
||||||
<< "got no answer from " << requests[index].destination << ":"
|
|
||||||
<< requests[index].path << " with error " << res.status;
|
|
||||||
}
|
|
||||||
if (nrDone >= requests.size()) {
|
|
||||||
// We are done, all results are in!
|
|
||||||
return nrGood;
|
|
||||||
}
|
}
|
||||||
|
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
||||||
|
<< "got BACKEND_UNAVAILABLE or TIMEOUT from "
|
||||||
|
<< requests[index].destination << ":" << requests[index].path;
|
||||||
|
} else { // a "proper error"
|
||||||
|
requests[index].result = res;
|
||||||
|
requests[index].done = true;
|
||||||
|
nrDone++;
|
||||||
|
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
||||||
|
<< "got no answer from " << requests[index].destination << ":"
|
||||||
|
<< requests[index].path << " with error " << res.status;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
LOG_TOPIC(ERR, Logger::CLUSTER) << "ClusterComm::performRequests: "
|
||||||
<< "caught exception, ignoring...";
|
<< "caught exception, ignoring...";
|
||||||
|
|
Loading…
Reference in New Issue