1
0
Fork 0

fixing issue when disaster recovered agent has new endpoint (#5809)

This commit is contained in:
Kaveh Vahedipour 2018-07-11 11:19:41 +02:00 committed by Max Neunhöffer
parent cf39008acb
commit 7b40a61b85
3 changed files with 36 additions and 22 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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();