@@ -133,7 +133,7 @@ void IcingaDB::ConfigStaticInitialize()
133133 IcingaDB::NextCheckUpdatedHandler (checkable);
134134 });
135135
136- DependencyGroup::OnMembersChanged.connect (&IcingaDB::DependencyGroupsChangedHandler );
136+ DependencyGroup::OnMembersChanged.connect (&IcingaDB::DependencyGroupChangedHandler );
137137
138138 Service::OnHostProblemChanged.connect ([](const Service::Ptr& service, const CheckResult::Ptr&, const MessageOrigin::Ptr&) {
139139 IcingaDB::HostProblemChangedHandler (service);
@@ -2803,59 +2803,69 @@ void IcingaDB::SendCustomVarsChanged(const ConfigObject::Ptr& object, const Dict
28032803 }
28042804}
28052805
2806- void IcingaDB::SendDependencyGroupsChanged (const Dependency ::Ptr& dep , const std::vector<DependencyGroup:: Ptr>& outdatedGroups )
2806+ void IcingaDB::SendDependencyGroupChanged (const DependencyGroup ::Ptr& modifiedGroup , const Dependency:: Ptr& member )
28072807{
28082808 if (!m_Rcon || !m_Rcon->IsConnected ()) {
28092809 return ;
28102810 }
28112811
2812- auto parent (dep->GetParent ());
2813- auto child (dep->GetChild ());
2812+ auto child (member->GetChild ());
28142813 if (!child->HasAnyDependencies ()) {
28152814 // If the child Checkable has no parent and reverse dependencies, we can safely remove the dependency node.
28162815 DeleteRelationship (GetObjectIdentifier (child), " dependency:node" );
28172816 }
28182817
28192818 RedisConnection::Queries hdels, xAdds;
2820- auto deleteState ([this , &hdels, &xAdds](const String& redisKey , const String& id ) {
2819+ auto deleteState ([this , &hdels, &xAdds](const String& id , const String& redisKey ) {
28212820 hdels.emplace_back (RedisConnection::Query{" HDEL" , m_PrefixConfigObject + redisKey, id});
28222821 xAdds.emplace_back (RedisConnection::Query{
28232822 " XADD" , " icinga:runtime:state" , " MAXLEN" , " ~" , " 1000000" , " *" , " runtime_type" , " delete" ,
28242823 " redis_key" , m_PrefixConfigObject + redisKey, " id" , id
28252824 });
28262825 });
28272826
2828- if (dep->GetRedundancyGroup ().IsEmpty () && !dep->IsActive () && dep->GetExtension (" ConfigObjectDeleted" )) {
2829- auto identifier (HashValue (new Array{GetObjectIdentifier (child), GetObjectIdentifier (parent)}));
2827+ auto parent (member->GetParent ());
2828+ if (!modifiedGroup->IsRedundancyGroup () && !member->IsActive () && member->GetExtension (" ConfigObjectDeleted" )) {
2829+ auto edgeId (HashValue (new Array{GetObjectIdentifier (child), GetObjectIdentifier (parent)}));
28302830 // Remove the edge between the parent and child Checkable linked through the removed dependency.
2831- DeleteRelationship (identifier, " dependency:edge" );
2832- // The dependency object is going to be deleted, so we need to remove its state from Redis as well.
2833- deleteState (" dependency:edge:state" , identifier);
2834- }
2831+ DeleteRelationship (edgeId, " dependency:edge" );
2832+
2833+ if (!modifiedGroup->HasMembers () || !modifiedGroup->HasIdenticalMember (member)) {
2834+ DependencyGroup::Ptr dummyGroup (new DependencyGroup (" " , member));
2835+ // In order to recreate the edge state ID, we need to copy the members of the modified group
2836+ // to a dummy one and use its composite key to generate its previous edge state ID.
2837+ for (auto dependency : modifiedGroup->GetMembers (child.get ())) {
2838+ dummyGroup->AddMember (dependency);
2839+ }
28352840
2836- auto newGroups (child->GetDependencyGroups ());
2837- for (auto & group : outdatedGroups) {
2838- String redundancyGroupId (group->GetIcingaDBIdentifier ());
2839- bool sameCompositeKey (redundancyGroupId == HashValue (new Array{m_EnvironmentId, group->GetCompositeKey ()}));
2840- if (!sameCompositeKey || !group->HasMembers () || std::find (newGroups.begin (), newGroups.end (), group) == newGroups.end ()) {
2841+ deleteState (
2842+ // Keep this edge state ID generation in sync with the one in SerializeDependencyEdgeState.
2843+ HashValue (new Array{dummyGroup->GetCompositeKey (), GetObjectIdentifier (parent)}),
2844+ " dependency:edge:state"
2845+ );
2846+ }
2847+ } else if (modifiedGroup->IsRedundancyGroup ()) {
2848+ auto newGroups (child->GetDependencyGroups ());
2849+ String redundancyGroupId (modifiedGroup->GetIcingaDBIdentifier ());
2850+ bool sameCompositeKey (redundancyGroupId == HashValue (new Array{m_EnvironmentId, modifiedGroup->GetCompositeKey ()}));
2851+ if (!sameCompositeKey || !modifiedGroup->HasMembers () || std::find (newGroups.begin (), newGroups.end (), modifiedGroup) == newGroups.end ()) {
28412852 // Remove the connection from the child Checkable to the redundancy group.
28422853 DeleteRelationship (HashValue (new Array{GetObjectIdentifier (child), redundancyGroupId}), " dependency:edge" );
28432854
2844- if (!sameCompositeKey || !group ->HasMembers ()) {
2845- auto members (group ->GetMembers (child.get ()));
2846- members.emplace_back (dep );
2847- for (auto & member : members) {
2855+ if (!sameCompositeKey || !modifiedGroup ->HasMembers ()) {
2856+ auto members (modifiedGroup ->GetMembers (child.get ()));
2857+ members.emplace_back (member );
2858+ for (auto & dependency : members) {
28482859 // Remove the connection from the redundancy group to the parent Checkable of the removed
28492860 // dependency, if there's no other member in the redundancy group that references that very
2850- // same parent Checkable or the dependency Group 's Icinga DB identifier has changed.
2851- auto groupParentId (HashValue (new Array{redundancyGroupId, GetObjectIdentifier (member ->GetParent ())}));
2852- DeleteRelationship (groupParentId , " dependency:edge" );
2853- deleteState (" dependency:edge:state" , groupParentId );
2861+ // same parent Checkable or the redundancy group 's Icinga DB identifier has changed.
2862+ auto id (HashValue (new Array{redundancyGroupId, GetObjectIdentifier (dependency ->GetParent ())}));
2863+ DeleteRelationship (id , " dependency:edge" );
2864+ deleteState (id, " dependency:edge:state" );
28542865 }
28552866
2856- // Remove the group entirely as it either has no members left or it's Icinga DB identifier has changed.
2857- deleteState (" dependency:edge:state" , redundancyGroupId);
2858- deleteState (" redundancygroup:state" , redundancyGroupId);
2867+ deleteState (redundancyGroupId, " dependency:edge:state" );
2868+ deleteState (redundancyGroupId, " redundancygroup:state" );
28592869 DeleteRelationship (redundancyGroupId, " dependency:node" );
28602870 DeleteRelationship (redundancyGroupId, " redundancygroup" );
28612871 }
@@ -2865,16 +2875,16 @@ void IcingaDB::SendDependencyGroupsChanged(const Dependency::Ptr& dep, const std
28652875 if (!hdels.empty ()) {
28662876 m_Rcon->FireAndForgetQueries (std::move (hdels), Prio::RuntimeStateSync);
28672877 m_Rcon->FireAndForgetQueries (std::move (xAdds), Prio::RuntimeStateStream, {0 , 1 });
2878+ }
28682879
2869- if (!newGroups.empty ()) {
2870- std::map<String, RedisConnection::Query> hMSets;
2871- std::vector<Dictionary::Ptr> runtimeUpdates;
2872- InsertCheckableDependencies (child, hMSets, &runtimeUpdates);
2880+ if (child->HasAnyDependencies ()) {
2881+ std::map<String, RedisConnection::Query> hMSets;
2882+ std::vector<Dictionary::Ptr> runtimeUpdates;
2883+ InsertCheckableDependencies (child, hMSets, &runtimeUpdates);
2884+ ExecuteRedisTransaction (hMSets, runtimeUpdates);
28732885
2874- ExecuteRedisTransaction (hMSets, runtimeUpdates);
2875- UpdateState (child, StateUpdate::Full);
2876- }
2877- }
2886+ UpdateState (child, StateUpdate::Full);
2887+ }
28782888
28792889 // The affect{ed,s}_children might now have different outcome, so we need to update the parent Checkable as well.
28802890 SendConfigUpdate (parent, true );
@@ -3163,10 +3173,10 @@ void IcingaDB::NextCheckUpdatedHandler(const Checkable::Ptr& checkable)
31633173 }
31643174}
31653175
3166- void IcingaDB::DependencyGroupsChangedHandler (const Dependency ::Ptr& dep , const std::vector<DependencyGroup:: Ptr>& outdatedGroups )
3176+ void IcingaDB::DependencyGroupChangedHandler (const DependencyGroup ::Ptr& modifiedGroup , const Dependency:: Ptr& member )
31673177{
31683178 for (auto & rw : ConfigType::GetObjectsByType<IcingaDB>()) {
3169- rw->SendDependencyGroupsChanged (dep, outdatedGroups );
3179+ rw->SendDependencyGroupChanged (modifiedGroup, member );
31703180 }
31713181}
31723182
0 commit comments