IcingaDB: Don't send useless dependencies state updates

This commit is contained in:
Yonas Habteab 2025-02-28 17:20:03 +01:00
parent da637c3741
commit 945a79e37f
2 changed files with 19 additions and 3 deletions

View File

@ -1357,8 +1357,10 @@ void IcingaDB::UpdateState(const Checkable::Ptr& checkable, StateUpdate mode)
*
* @param checkable The Checkable you want to send the dependencies state update for
* @param onlyDependencyGroup If set, send state updates only for this dependency group and its dependencies.
* @param seenGroups A container to track already processed DependencyGroups to avoid duplicate state updates.
*/
void IcingaDB::UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& onlyDependencyGroup) const
void IcingaDB::UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& onlyDependencyGroup,
std::set<DependencyGroup*>* seenGroups) const
{
if (!m_Rcon || !m_Rcon->IsConnected()) {
return;
@ -1396,6 +1398,18 @@ void IcingaDB::UpdateDependenciesState(const Checkable::Ptr& checkable, const De
continue;
}
if (seenGroups && !seenGroups->insert(dependencyGroup.get()).second) {
// Usually, if the seenGroups set is provided, IcingaDB is triggering a runtime state update for ALL
// children of a given initiator Checkable (parent). In such cases, we may end up with lots of useless
// state updates as all the children of a non-redundant group a) share the same entry in the database b)
// it doesn't matter which child triggers the state update first all the subsequent updates are just useless.
//
// Likewise, for redundancy groups, all children of a redundancy group share the same set of parents
// and thus the resulting state information would be the same from each child Checkable perspective.
// So, serializing the redundancy group state information only once is sufficient.
continue;
}
auto dependencies(dependencyGroup->GetDependenciesForChild(checkable.get()));
std::sort(dependencies.begin(), dependencies.end(), [](const Dependency::Ptr& lhs, const Dependency::Ptr& rhs) {
return lhs->GetParent() < rhs->GetParent();
@ -3096,9 +3110,10 @@ void IcingaDB::StateChangeHandler(const ConfigObject::Ptr& object, const CheckRe
void IcingaDB::ReachabilityChangeHandler(const std::set<Checkable::Ptr>& children)
{
for (const IcingaDB::Ptr& rw : ConfigType::GetObjectsByType<IcingaDB>()) {
std::set<DependencyGroup*> seenGroups;
for (auto& checkable : children) {
rw->UpdateState(checkable, StateUpdate::Full);
rw->UpdateDependenciesState(checkable);
rw->UpdateDependenciesState(checkable, nullptr, &seenGroups);
}
}
}

View File

@ -114,7 +114,8 @@ private:
std::vector<Dictionary::Ptr>* runtimeUpdates, const DependencyGroup::Ptr& onlyDependencyGroup = nullptr);
void InsertObjectDependencies(const ConfigObject::Ptr& object, const String typeName, std::map<String, std::vector<String>>& hMSets,
std::vector<Dictionary::Ptr>& runtimeUpdates, bool runtimeUpdate);
void UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& onlyDependencyGroup = nullptr) const;
void UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& onlyDependencyGroup = nullptr,
std::set<DependencyGroup*>* seenGroups = nullptr) const;
void UpdateState(const Checkable::Ptr& checkable, StateUpdate mode);
void SendConfigUpdate(const ConfigObject::Ptr& object, bool runtimeUpdate);
void CreateConfigUpdate(const ConfigObject::Ptr& object, const String type, std::map<String, std::vector<String>>& hMSets,