Improve code docs for cluster message routing conditions

refs #6781
This commit is contained in:
Michael Friedrich 2019-04-10 14:17:36 +02:00
parent d459f3448d
commit b24a3be083
2 changed files with 44 additions and 30 deletions

View File

@ -964,21 +964,21 @@ void ApiListener::SyncSendMessage(const Endpoint::Ptr& endpoint, const Dictionar
} }
} }
bool ApiListener::RelayMessageOne(const Zone::Ptr& targetZone, const MessageOrigin::Ptr& origin, const Dictionary::Ptr& message, const Endpoint::Ptr& currentMaster) bool ApiListener::RelayMessageOne(const Zone::Ptr& targetZone, const MessageOrigin::Ptr& origin, const Dictionary::Ptr& message, const Endpoint::Ptr& currentZoneMaster)
{ {
ASSERT(targetZone); ASSERT(targetZone);
Zone::Ptr myZone = Zone::GetLocalZone(); Zone::Ptr localZone = Zone::GetLocalZone();
/* only relay the message to a) the same zone, b) the parent zone and c) direct child zones. Exception is a global zone. */ /* only relay the message to a) the same local zone, b) the parent zone and c) direct child zones. Exception is a global zone. */
if (!targetZone->GetGlobal() && if (!targetZone->GetGlobal() &&
targetZone != myZone && targetZone != localZone &&
targetZone != myZone->GetParent() && targetZone != localZone->GetParent() &&
targetZone->GetParent() != myZone) { targetZone->GetParent() != localZone) {
return true; return true;
} }
Endpoint::Ptr myEndpoint = GetLocalEndpoint(); Endpoint::Ptr localEndpoint = GetLocalEndpoint();
std::vector<Endpoint::Ptr> skippedEndpoints; std::vector<Endpoint::Ptr> skippedEndpoints;
@ -987,11 +987,11 @@ bool ApiListener::RelayMessageOne(const Zone::Ptr& targetZone, const MessageOrig
std::set<Endpoint::Ptr> targetEndpoints; std::set<Endpoint::Ptr> targetEndpoints;
if (targetZone->GetGlobal()) { if (targetZone->GetGlobal()) {
targetEndpoints = myZone->GetEndpoints(); targetEndpoints = localZone->GetEndpoints();
for (const Zone::Ptr& zone : ConfigType::GetObjectsByType<Zone>()) { for (const Zone::Ptr& zone : ConfigType::GetObjectsByType<Zone>()) {
/* Fetch immediate child zone members */ /* Fetch immediate child zone members */
if (zone->GetParent() == myZone) { if (zone->GetParent() == localZone) {
std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints(); std::set<Endpoint::Ptr> endpoints = zone->GetEndpoints();
targetEndpoints.insert(endpoints.begin(), endpoints.end()); targetEndpoints.insert(endpoints.begin(), endpoints.end());
} }
@ -1000,16 +1000,16 @@ bool ApiListener::RelayMessageOne(const Zone::Ptr& targetZone, const MessageOrig
targetEndpoints = targetZone->GetEndpoints(); targetEndpoints = targetZone->GetEndpoints();
} }
for (const Endpoint::Ptr& endpoint : targetEndpoints) { for (const Endpoint::Ptr& targetEndpoint : targetEndpoints) {
/* don't relay messages to ourselves */ /* Don't relay messages to ourselves. */
if (endpoint == GetLocalEndpoint()) if (targetEndpoint == localEndpoint)
continue; continue;
log_needed = true; log_needed = true;
/* don't relay messages to disconnected endpoints */ /* Don't relay messages to disconnected endpoints. */
if (!endpoint->GetConnected()) { if (!targetEndpoint->GetConnected()) {
if (targetZone == myZone) if (targetZone == localZone)
log_done = false; log_done = false;
continue; continue;
@ -1017,40 +1017,54 @@ bool ApiListener::RelayMessageOne(const Zone::Ptr& targetZone, const MessageOrig
log_done = true; log_done = true;
/* don't relay the message to the zone through more than one endpoint unless this is our own zone */ /* Don't relay the message to the zone through more than one endpoint unless this is our own zone.
if (relayed && targetZone != myZone) { * 'relayed' is set to true on success below, enabling the checks in the second iteration.
skippedEndpoints.push_back(endpoint); */
if (relayed && targetZone != localZone) {
skippedEndpoints.push_back(targetEndpoint);
continue; continue;
} }
/* don't relay messages back to the endpoint which we got the message from */ /* Don't relay messages back to the endpoint which we got the message from. */
if (origin && origin->FromClient && endpoint == origin->FromClient->GetEndpoint()) { if (origin && origin->FromClient && targetEndpoint == origin->FromClient->GetEndpoint()) {
skippedEndpoints.push_back(endpoint); skippedEndpoints.push_back(targetEndpoint);
continue; continue;
} }
/* don't relay messages back to the zone which we got the message from */ /* Don't relay messages back to the zone which we got the message from. */
if (origin && origin->FromZone && targetZone == origin->FromZone) { if (origin && origin->FromZone && targetZone == origin->FromZone) {
skippedEndpoints.push_back(endpoint); skippedEndpoints.push_back(targetEndpoint);
continue; continue;
} }
/* only relay message to the master if we're not currently the master */ /* Only relay message to the zone master if we're not currently the zone master.
if (currentMaster != myEndpoint && currentMaster != endpoint) { * e1 is zone master, e2 and e3 are zone members.
skippedEndpoints.push_back(endpoint); *
* Message is sent from e2 or e3:
* !isMaster == true
* targetEndpoint e1 is zone master -> send the message
* targetEndpoint e3 is not zone master -> skip it, avoid routing loops
*
* Message is sent from e1:
* !isMaster == false -> send the messages to e2 and e3 being the zone routing master.
*/
bool isMaster = (currentZoneMaster == localEndpoint);
if (!isMaster && targetEndpoint != currentZoneMaster) {
skippedEndpoints.push_back(targetEndpoint);
continue; continue;
} }
relayed = true; relayed = true;
SyncSendMessage(endpoint, message); SyncSendMessage(targetEndpoint, message);
} }
if (!skippedEndpoints.empty()) { if (!skippedEndpoints.empty()) {
double ts = message->Get("ts"); double ts = message->Get("ts");
for (const Endpoint::Ptr& endpoint : skippedEndpoints) for (const Endpoint::Ptr& skippedEndpoint : skippedEndpoints)
endpoint->SetLocalLogPosition(ts); skippedEndpoint->SetLocalLogPosition(ts);
} }
return !log_needed || log_done; return !log_needed || log_done;

View File

@ -141,7 +141,7 @@ private:
Stream::Ptr m_LogFile; Stream::Ptr m_LogFile;
size_t m_LogMessageCount{0}; size_t m_LogMessageCount{0};
bool RelayMessageOne(const Zone::Ptr& zone, const MessageOrigin::Ptr& origin, const Dictionary::Ptr& message, const Endpoint::Ptr& currentMaster); bool RelayMessageOne(const Zone::Ptr& zone, const MessageOrigin::Ptr& origin, const Dictionary::Ptr& message, const Endpoint::Ptr& currentZoneMaster);
void SyncRelayMessage(const MessageOrigin::Ptr& origin, const ConfigObject::Ptr& secobj, const Dictionary::Ptr& message, bool log); void SyncRelayMessage(const MessageOrigin::Ptr& origin, const ConfigObject::Ptr& secobj, const Dictionary::Ptr& message, bool log);
void PersistMessage(const Dictionary::Ptr& message, const ConfigObject::Ptr& secobj); void PersistMessage(const Dictionary::Ptr& message, const ConfigObject::Ptr& secobj);