From e627dcce1bdfa48acd9b3bdf6a2bf4254e89ab43 Mon Sep 17 00:00:00 2001 From: Henrik Triem Date: Mon, 27 Jan 2020 15:58:58 +0100 Subject: [PATCH] Change the order of the object sync --- lib/remote/apilistener-configsync.cpp | 46 ++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/remote/apilistener-configsync.cpp b/lib/remote/apilistener-configsync.cpp index a12db0bca73..c1767bfc6b3 100644 --- a/lib/remote/apilistener-configsync.cpp +++ b/lib/remote/apilistener-configsync.cpp @@ -443,22 +443,52 @@ void ApiListener::SendRuntimeConfigObjects(const JsonRpcConnection::Ptr& aclient Log(LogInformation, "ApiListener") << "Syncing runtime objects to endpoint '" << endpoint->GetName() << "'."; + std::set types; + std::set completed_types; + for (const Type::Ptr& type : Type::GetAllTypes()) { - auto *dtype = dynamic_cast(type.get()); + if (ConfigObject::TypeInstance->IsAssignableFrom(type)) + types.insert(type); + } + + while (types.size() != completed_types.size()) { + for (const Type::Ptr& type : types) { + if (completed_types.find(type) != completed_types.end()) + continue; - if (!dtype) - continue; + bool unresolved_dep = false; - for (const ConfigObject::Ptr& object : dtype->GetObjects()) { - /* don't sync objects for non-matching parent-child zones */ - if (!azone->CanAccessObject(object)) + /* 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; - /* send the config object to the connected client */ - UpdateConfigObject(object, nullptr, aclient); + auto *dtype = dynamic_cast(type.get()); + if (!dtype) + continue; + + for (const ConfigObject::Ptr& object : dtype->GetObjects()) { + /* don't sync objects for non-matching parent-child zones */ + if (!azone->CanAccessObject(object)) + continue; + + /* send the config object to the connected client */ + UpdateConfigObject(object, nullptr, aclient); + } + + completed_types.insert(type); + } } + Log(LogInformation, "ApiListener") << "Finished syncing runtime objects to endpoint '" << endpoint->GetName() << "'."; }