mirror of https://gitee.com/bigwinds/arangodb
fixing issue when disaster recovered agent has new endpoint (#5809)
This commit is contained in:
parent
cf39008acb
commit
7b40a61b85
|
@ -1672,14 +1672,11 @@ query_t Agent::gossip(query_t const& in, bool isCallback, size_t version) {
|
|||
|
||||
|
||||
LOG_TOPIC(TRACE, Logger::AGENCY) << "Received gossip " << slice.toJson();
|
||||
|
||||
std::unordered_map<std::string, std::string> incoming;
|
||||
for (auto const& pair : VPackObjectIterator(pslice)) {
|
||||
if (!pair.value.isString()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
20004, "Gossip message pool must contain string parameters");
|
||||
}
|
||||
incoming[pair.key.copyString()] = pair.value.copyString();
|
||||
}
|
||||
|
||||
query_t out = std::make_shared<Builder>();
|
||||
|
@ -1697,16 +1694,12 @@ query_t Agent::gossip(query_t const& in, bool isCallback, size_t version) {
|
|||
}
|
||||
}
|
||||
|
||||
for (auto const& i : incoming) {
|
||||
|
||||
/// disagreement over pool membership: fatal!
|
||||
if (!_config.addToPool(i)) {
|
||||
if (!_config.upsertPool(pslice, id)) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY) << "Discrepancy in agent pool!";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!isCallback) { // no gain in callback to a callback.
|
||||
auto pool = _config.pool();
|
||||
auto active = _config.active();
|
||||
|
|
|
@ -265,16 +265,25 @@ void config_t::eraseFromGossipPeers(std::string const& endpoint) {
|
|||
}
|
||||
}
|
||||
|
||||
bool config_t::addToPool(std::pair<std::string, std::string> const& i) {
|
||||
bool config_t::upsertPool(
|
||||
VPackSlice const& otherPool, std::string const& otherId) {
|
||||
WRITE_LOCKER(readLocker, _lock);
|
||||
if (_pool.find(i.first) == _pool.end()) {
|
||||
for (auto const& entry : VPackObjectIterator(otherPool)) {
|
||||
auto const id = entry.key.copyString();
|
||||
auto const endpoint = entry.value.copyString();
|
||||
if (_pool.find(id) == _pool.end()) {
|
||||
LOG_TOPIC(INFO, Logger::AGENCY)
|
||||
<< "Adding " << i.first << "(" << i.second << ") to agent pool";
|
||||
_pool[i.first] = i.second;
|
||||
<< "Adding " << id << "(" << endpoint << ") to agent pool";
|
||||
_pool[id] = endpoint;
|
||||
++_version;
|
||||
} else {
|
||||
if (_pool.at(i.first) != i.second) { /// discrepancy!
|
||||
if (_pool.at(id) != endpoint) {
|
||||
if (id != otherId) { /// discrepancy!
|
||||
return false;
|
||||
} else { /// we trust the other guy on his own endpoint
|
||||
_pool.at(id) = endpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -127,8 +127,20 @@ struct config_t {
|
|||
/// @brief wait for sync requested
|
||||
bool waitForSync() const;
|
||||
|
||||
/// @brief add pool member
|
||||
bool addToPool(std::pair<std::string, std::string> const& i);
|
||||
/**
|
||||
* @brief Verify other agent's pool against our own:
|
||||
* - We only get here, if our pool is not complete yet or the
|
||||
* id is member of this agency
|
||||
* - We match their pool to ours and allow only for an update
|
||||
* of it's own endpoint
|
||||
*
|
||||
* @param otherPool Other agent's pool
|
||||
* @param otherId Other agent's id
|
||||
*
|
||||
* @return Success
|
||||
*/
|
||||
bool upsertPool(
|
||||
VPackSlice const& otherPool, std::string const& otherId);
|
||||
|
||||
/// @brief active agency size
|
||||
void activate();
|
||||
|
|
Loading…
Reference in New Issue