mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-29 08:34:20 +02:00
Checkable: Emit boost signals when changing dependency groups at runtime
This commit is contained in:
parent
b462028b4f
commit
806fff950c
@ -75,7 +75,7 @@ static std::variant<Checkable*, String> GetDependencyGroupKey(const Dependency::
|
|||||||
*/
|
*/
|
||||||
void Checkable::AddDependency(const Dependency::Ptr& dependency)
|
void Checkable::AddDependency(const Dependency::Ptr& dependency)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_DependencyMutex);
|
std::unique_lock lock(m_DependencyMutex);
|
||||||
|
|
||||||
auto dependencyGroupKey(GetDependencyGroupKey(dependency));
|
auto dependencyGroupKey(GetDependencyGroupKey(dependency));
|
||||||
if (!m_DependencyGroupsPushedToRegistry) {
|
if (!m_DependencyGroupsPushedToRegistry) {
|
||||||
@ -88,27 +88,38 @@ void Checkable::AddDependency(const Dependency::Ptr& dependency)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::set<Dependency::Ptr> dependencies;
|
std::set<Dependency::Ptr> dependencies;
|
||||||
|
bool removeGroup(false);
|
||||||
|
|
||||||
|
DependencyGroup::Ptr existingGroup;
|
||||||
if (auto it(m_DependencyGroups.find(dependencyGroupKey)); it != m_DependencyGroups.end()) {
|
if (auto it(m_DependencyGroups.find(dependencyGroupKey)); it != m_DependencyGroups.end()) {
|
||||||
dependencies = DependencyGroup::Unregister(it->second, this);
|
existingGroup = it->second;
|
||||||
|
std::tie(dependencies, removeGroup) = DependencyGroup::Unregister(existingGroup, this);
|
||||||
m_DependencyGroups.erase(it);
|
m_DependencyGroups.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies.emplace(dependency);
|
dependencies.emplace(dependency);
|
||||||
|
|
||||||
m_DependencyGroups.emplace(
|
auto dependencyGroup(DependencyGroup::Register(new DependencyGroup(dependency->GetRedundancyGroup(), dependencies)));
|
||||||
dependencyGroupKey,
|
m_DependencyGroups.emplace(dependencyGroupKey, dependencyGroup);
|
||||||
DependencyGroup::Register(new DependencyGroup(dependency->GetRedundancyGroup(), dependencies))
|
|
||||||
);
|
lock.unlock();
|
||||||
|
|
||||||
|
if (existingGroup) {
|
||||||
|
dependencies.erase(dependency);
|
||||||
|
DependencyGroup::OnChildRemoved(existingGroup, {dependencies.begin(), dependencies.end()}, removeGroup);
|
||||||
|
}
|
||||||
|
DependencyGroup::OnChildRegistered(this, dependencyGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the provided dependency from the current Checkable list of dependencies.
|
* Remove the provided dependency from the current Checkable list of dependencies.
|
||||||
*
|
*
|
||||||
* @param dependency The dependency to remove.
|
* @param dependency The dependency to remove.
|
||||||
|
* @param runtimeRemoved Whether the given dependency object is being removed at runtime.
|
||||||
*/
|
*/
|
||||||
void Checkable::RemoveDependency(const Dependency::Ptr& dependency)
|
void Checkable::RemoveDependency(const Dependency::Ptr& dependency, bool runtimeRemoved)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_DependencyMutex);
|
std::unique_lock lock(m_DependencyMutex);
|
||||||
|
|
||||||
auto dependencyGroupKey(GetDependencyGroupKey(dependency));
|
auto dependencyGroupKey(GetDependencyGroupKey(dependency));
|
||||||
auto it = m_DependencyGroups.find(dependencyGroupKey);
|
auto it = m_DependencyGroups.find(dependencyGroupKey);
|
||||||
@ -116,15 +127,27 @@ void Checkable::RemoveDependency(const Dependency::Ptr& dependency)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<Dependency::Ptr> dependencies(DependencyGroup::Unregister(it->second, this));
|
DependencyGroup::Ptr existingGroup(it->second);
|
||||||
|
auto [dependencies, removeGroup] = DependencyGroup::Unregister(existingGroup, this);
|
||||||
|
|
||||||
m_DependencyGroups.erase(it);
|
m_DependencyGroups.erase(it);
|
||||||
dependencies.erase(dependency);
|
dependencies.erase(dependency);
|
||||||
|
|
||||||
|
DependencyGroup::Ptr newDependencyGroup;
|
||||||
if (!dependencies.empty()) {
|
if (!dependencies.empty()) {
|
||||||
m_DependencyGroups.emplace(
|
newDependencyGroup = DependencyGroup::Register(new DependencyGroup(dependency->GetRedundancyGroup(), dependencies));
|
||||||
dependencyGroupKey,
|
m_DependencyGroups.emplace(dependencyGroupKey, newDependencyGroup);
|
||||||
DependencyGroup::Register(new DependencyGroup(dependency->GetRedundancyGroup(), dependencies))
|
}
|
||||||
);
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
if (runtimeRemoved) {
|
||||||
|
dependencies.emplace(dependency);
|
||||||
|
DependencyGroup::OnChildRemoved(existingGroup, {dependencies.begin(), dependencies.end()}, removeGroup);
|
||||||
|
|
||||||
|
if (newDependencyGroup) {
|
||||||
|
DependencyGroup::OnChildRegistered(this, newDependencyGroup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ public:
|
|||||||
void PushDependencyGroupsToRegistry();
|
void PushDependencyGroupsToRegistry();
|
||||||
std::vector<intrusive_ptr<DependencyGroup>> GetDependencyGroups() const;
|
std::vector<intrusive_ptr<DependencyGroup>> GetDependencyGroups() const;
|
||||||
void AddDependency(const intrusive_ptr<Dependency>& dependency);
|
void AddDependency(const intrusive_ptr<Dependency>& dependency);
|
||||||
void RemoveDependency(const intrusive_ptr<Dependency>& dependency);
|
void RemoveDependency(const intrusive_ptr<Dependency>& dependency, bool runtimeRemoved = false);
|
||||||
std::vector<intrusive_ptr<Dependency> > GetDependencies() const;
|
std::vector<intrusive_ptr<Dependency> > GetDependencies() const;
|
||||||
bool HasAnyDependencies() const;
|
bool HasAnyDependencies() const;
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
boost::signals2::signal<void(const Checkable::Ptr&, const DependencyGroup::Ptr&)> DependencyGroup::OnChildRegistered;
|
||||||
|
boost::signals2::signal<void(const DependencyGroup::Ptr&, const std::vector<Dependency::Ptr>&, bool)> DependencyGroup::OnChildRemoved;
|
||||||
|
|
||||||
std::mutex DependencyGroup::m_RegistryMutex;
|
std::mutex DependencyGroup::m_RegistryMutex;
|
||||||
DependencyGroup::RegistryType DependencyGroup::m_Registry;
|
DependencyGroup::RegistryType DependencyGroup::m_Registry;
|
||||||
|
|
||||||
@ -36,15 +39,15 @@ DependencyGroup::Ptr DependencyGroup::Register(const DependencyGroup::Ptr& depen
|
|||||||
* @param dependencyGroup The dependency group to unregister the child Checkable from.
|
* @param dependencyGroup The dependency group to unregister the child Checkable from.
|
||||||
* @param child The child Checkable to detach from the dependency group.
|
* @param child The child Checkable to detach from the dependency group.
|
||||||
*
|
*
|
||||||
* @return - Returns the dependency objects of the child Checkable that were member of the provided dependency group.
|
* @return - Returns the dependency objects of the child Checkable that were member of the provided dependency group
|
||||||
|
* and a boolean indicating whether the dependency group has been erased from the global registry.
|
||||||
*/
|
*/
|
||||||
std::set<Dependency::Ptr> DependencyGroup::Unregister(const DependencyGroup::Ptr& dependencyGroup, const Checkable::Ptr& child)
|
std::pair<std::set<Dependency::Ptr>, bool> DependencyGroup::Unregister(const DependencyGroup::Ptr& dependencyGroup, const Checkable::Ptr& child)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_RegistryMutex);
|
std::lock_guard lock(m_RegistryMutex);
|
||||||
std::vector<Dependency::Ptr> dependencies;
|
|
||||||
if (auto it(m_Registry.find(dependencyGroup)); it != m_Registry.end()) {
|
if (auto it(m_Registry.find(dependencyGroup)); it != m_Registry.end()) {
|
||||||
const auto& existingGroup(*it);
|
auto existingGroup(*it);
|
||||||
dependencies = existingGroup->GetDependenciesForChild(child.get());
|
auto dependencies(existingGroup->GetDependenciesForChild(child.get()));
|
||||||
|
|
||||||
for (const auto& dependency : dependencies) {
|
for (const auto& dependency : dependencies) {
|
||||||
existingGroup->RemoveDependency(dependency);
|
existingGroup->RemoveDependency(dependency);
|
||||||
@ -53,8 +56,9 @@ std::set<Dependency::Ptr> DependencyGroup::Unregister(const DependencyGroup::Ptr
|
|||||||
if (existingGroup->IsEmpty()) {
|
if (existingGroup->IsEmpty()) {
|
||||||
m_Registry.erase(it);
|
m_Registry.erase(it);
|
||||||
}
|
}
|
||||||
|
return {{dependencies.begin(), dependencies.end()}, existingGroup->IsEmpty()};
|
||||||
}
|
}
|
||||||
return {dependencies.begin(), dependencies.end()};
|
return {{}, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,7 +259,7 @@ void Dependency::Stop(bool runtimeRemoved)
|
|||||||
{
|
{
|
||||||
ObjectImpl<Dependency>::Stop(runtimeRemoved);
|
ObjectImpl<Dependency>::Stop(runtimeRemoved);
|
||||||
|
|
||||||
GetChild()->RemoveDependency(this);
|
GetChild()->RemoveDependency(this, runtimeRemoved);
|
||||||
GetParent()->RemoveReverseDependency(this);
|
GetParent()->RemoveReverseDependency(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ public:
|
|||||||
DependencyGroup(String name, const std::set<Dependency::Ptr>& dependencies);
|
DependencyGroup(String name, const std::set<Dependency::Ptr>& dependencies);
|
||||||
|
|
||||||
static DependencyGroup::Ptr Register(const DependencyGroup::Ptr& dependencyGroup);
|
static DependencyGroup::Ptr Register(const DependencyGroup::Ptr& dependencyGroup);
|
||||||
static std::set<Dependency::Ptr> Unregister(const DependencyGroup::Ptr& dependencyGroup, const Checkable::Ptr& child);
|
static std::pair<std::set<Dependency::Ptr>, bool> Unregister(const DependencyGroup::Ptr& dependencyGroup, const Checkable::Ptr& child);
|
||||||
static size_t GetRegistrySize();
|
static size_t GetRegistrySize();
|
||||||
|
|
||||||
static CompositeKeyType MakeCompositeKeyFor(const Dependency::Ptr& dependency);
|
static CompositeKeyType MakeCompositeKeyFor(const Dependency::Ptr& dependency);
|
||||||
@ -171,6 +171,9 @@ public:
|
|||||||
|
|
||||||
State GetState(DependencyType dt = DependencyState, int rstack = 0) const;
|
State GetState(DependencyType dt = DependencyState, int rstack = 0) const;
|
||||||
|
|
||||||
|
static boost::signals2::signal<void(const Checkable::Ptr&, const DependencyGroup::Ptr&)> OnChildRegistered;
|
||||||
|
static boost::signals2::signal<void(const DependencyGroup::Ptr&, const std::vector<Dependency::Ptr>&, bool)> OnChildRemoved;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CopyDependenciesTo(const DependencyGroup::Ptr& dest);
|
void CopyDependenciesTo(const DependencyGroup::Ptr& dest);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user