mirror of https://github.com/Icinga/icinga2.git
Ensure that config object types are committed in dependent load order
This commit is contained in:
parent
81b9c9cef0
commit
13a8fa20f9
|
@ -443,27 +443,22 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
|
||||||
// noticably in environments with lots of objects and available threads.
|
// noticably in environments with lots of objects and available threads.
|
||||||
std::shuffle(std::begin(items), std::end(items), std::default_random_engine {});
|
std::shuffle(std::begin(items), std::end(items), std::default_random_engine {});
|
||||||
|
|
||||||
|
#ifdef I2_DEBUG
|
||||||
|
Log(LogDebug, "configitem")
|
||||||
|
<< "Committing " << items.size() << " new items.";
|
||||||
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
for (const auto& ip : items)
|
for (const auto& ip : items)
|
||||||
newItems.push_back(ip.first);
|
newItems.push_back(ip.first);
|
||||||
|
|
||||||
upq.ParallelFor(items, [](const ItemPair& ip) {
|
|
||||||
ip.first->Commit(ip.second);
|
|
||||||
});
|
|
||||||
|
|
||||||
upq.Join();
|
|
||||||
|
|
||||||
if (upq.HasExceptions())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::set<Type::Ptr> types;
|
std::set<Type::Ptr> types;
|
||||||
|
std::set<Type::Ptr> completed_types;
|
||||||
|
|
||||||
for (const Type::Ptr& type : Type::GetAllTypes()) {
|
for (const Type::Ptr& type : Type::GetAllTypes()) {
|
||||||
if (ConfigObject::TypeInstance->IsAssignableFrom(type))
|
if (ConfigObject::TypeInstance->IsAssignableFrom(type))
|
||||||
types.insert(type);
|
types.insert(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<Type::Ptr> completed_types;
|
|
||||||
|
|
||||||
while (types.size() != completed_types.size()) {
|
while (types.size() != completed_types.size()) {
|
||||||
for (const Type::Ptr& type : types) {
|
for (const Type::Ptr& type : types) {
|
||||||
if (completed_types.find(type) != completed_types.end())
|
if (completed_types.find(type) != completed_types.end())
|
||||||
|
@ -483,7 +478,60 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
|
||||||
if (unresolved_dep)
|
if (unresolved_dep)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
upq.ParallelFor(items, [&type](const ItemPair& ip) {
|
int commited_items = 0;
|
||||||
|
upq.ParallelFor(items, [&type, &commited_items](const ItemPair& ip) {
|
||||||
|
const ConfigItem::Ptr& item = ip.first;
|
||||||
|
|
||||||
|
if (item->m_Type != type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ip.first->Commit(ip.second);
|
||||||
|
commited_items++;
|
||||||
|
});
|
||||||
|
|
||||||
|
upq.Join();
|
||||||
|
|
||||||
|
completed_types.insert(type);
|
||||||
|
|
||||||
|
#ifdef I2_DEBUG
|
||||||
|
if (commited_items > 0)
|
||||||
|
Log(LogDebug, "configitem")
|
||||||
|
<< "Committed " << commited_items << " items of type '" << type->GetName() << "'.";
|
||||||
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
|
if (upq.HasExceptions())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef I2_DEBUG
|
||||||
|
Log(LogDebug, "configitem")
|
||||||
|
<< "Committed " << items.size() << " items.";
|
||||||
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
|
completed_types.clear();
|
||||||
|
|
||||||
|
while (types.size() != completed_types.size()) {
|
||||||
|
for (const Type::Ptr& type : types) {
|
||||||
|
if (completed_types.find(type) != completed_types.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool unresolved_dep = false;
|
||||||
|
|
||||||
|
/* skip this type (for now) if there are unresolved load dependencies */
|
||||||
|
for (const String& loadDep : type->GetLoadDependencies()) {
|
||||||
|
Type::Ptr pLoadDep = Type::GetByName(loadDep);
|
||||||
|
if (types.find(pLoadDep) != types.end() && completed_types.find(pLoadDep) == completed_types.end()) {
|
||||||
|
unresolved_dep = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unresolved_dep)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int notified_items = 0;
|
||||||
|
upq.ParallelFor(items, [&type, ¬ified_items](const ItemPair& ip) {
|
||||||
const ConfigItem::Ptr& item = ip.first;
|
const ConfigItem::Ptr& item = ip.first;
|
||||||
|
|
||||||
if (!item->m_Object || item->m_Type != type)
|
if (!item->m_Object || item->m_Type != type)
|
||||||
|
@ -491,6 +539,7 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
|
||||||
|
|
||||||
try {
|
try {
|
||||||
item->m_Object->OnAllConfigLoaded();
|
item->m_Object->OnAllConfigLoaded();
|
||||||
|
notified_items++;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
if (!item->m_IgnoreOnError)
|
if (!item->m_IgnoreOnError)
|
||||||
throw;
|
throw;
|
||||||
|
@ -511,11 +560,18 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
|
||||||
|
|
||||||
upq.Join();
|
upq.Join();
|
||||||
|
|
||||||
|
#ifdef I2_DEBUG
|
||||||
|
if (notified_items > 0)
|
||||||
|
Log(LogDebug, "configitem")
|
||||||
|
<< "Sent OnAllConfigLoaded to " << notified_items << " items of type '" << type->GetName() << "'.";
|
||||||
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
if (upq.HasExceptions())
|
if (upq.HasExceptions())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
notified_items = 0;
|
||||||
for (const String& loadDep : type->GetLoadDependencies()) {
|
for (const String& loadDep : type->GetLoadDependencies()) {
|
||||||
upq.ParallelFor(items, [loadDep, &type](const ItemPair& ip) {
|
upq.ParallelFor(items, [loadDep, &type, ¬ified_items](const ItemPair& ip) {
|
||||||
const ConfigItem::Ptr& item = ip.first;
|
const ConfigItem::Ptr& item = ip.first;
|
||||||
|
|
||||||
if (!item->m_Object || item->m_Type->GetName() != loadDep)
|
if (!item->m_Object || item->m_Type->GetName() != loadDep)
|
||||||
|
@ -523,14 +579,22 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
|
||||||
|
|
||||||
ActivationScope ascope(item->m_ActivationContext);
|
ActivationScope ascope(item->m_ActivationContext);
|
||||||
item->m_Object->CreateChildObjects(type);
|
item->m_Object->CreateChildObjects(type);
|
||||||
|
notified_items++;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
upq.Join();
|
upq.Join();
|
||||||
|
|
||||||
|
#ifdef I2_DEBUG
|
||||||
|
if (notified_items > 0)
|
||||||
|
Log(LogDebug, "configitem")
|
||||||
|
<< "Sent CreateChildObjects to " << notified_items << " items of type '" << type->GetName() << "'.";
|
||||||
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
if (upq.HasExceptions())
|
if (upq.HasExceptions())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Make sure to activate any additionally generated items
|
||||||
if (!CommitNewItems(context, upq, newItems))
|
if (!CommitNewItems(context, upq, newItems))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue