From: Michael Friedrich Date: Tue, 24 Nov 2015 14:25:55 +0000 (+0100) Subject: Improve performance for Zone::CanAccessObject X-Git-Tag: v2.5.0~702 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3adedcd0a55c94ae3ef6541278c85bd178b6c966;p=icinga2 Improve performance for Zone::CanAccessObject fixes #10711 --- diff --git a/lib/base/configobject.cpp b/lib/base/configobject.cpp index 9b59f69f0..00b4af1bb 100644 --- a/lib/base/configobject.cpp +++ b/lib/base/configobject.cpp @@ -440,7 +440,7 @@ void ConfigObject::OnConfigLoaded(void) void ConfigObject::OnAllConfigLoaded(void) { - /* Nothing to do here. */ + m_Zone = GetObject("Zone", GetZoneName()); } void ConfigObject::CreateChildObjects(const Type::Ptr& childType) @@ -684,3 +684,8 @@ ConfigObject::Ptr ConfigObject::GetObject(const String& type, const String& name return ConfigObject::Ptr(); return dtype->GetObject(name); } + +ConfigObject::Ptr ConfigObject::GetZone(void) const +{ + return m_Zone; +} diff --git a/lib/base/configobject.hpp b/lib/base/configobject.hpp index 1991d5c6e..94a69c323 100644 --- a/lib/base/configobject.hpp +++ b/lib/base/configobject.hpp @@ -53,6 +53,8 @@ public: Value GetExtension(const String& key); void ClearExtension(const String& key); + ConfigObject::Ptr GetZone(void) const; + void ModifyAttribute(const String& attr, const Value& value, bool updateVersion = true); void RestoreAttribute(const String& attr, bool updateVersion = true); bool IsAttributeModified(const String& attr) const; @@ -97,6 +99,8 @@ protected: explicit ConfigObject(void); private: + ConfigObject::Ptr m_Zone; + static void RestoreObject(const String& message, int attributeTypes); }; diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 653b7364b..b10d114ed 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -41,6 +41,7 @@ using namespace icinga; REGISTER_TYPE(ApiListener); boost::signals2::signal ApiListener::OnMasterChanged; +ApiListener::Ptr ApiListener::m_Instance; REGISTER_STATSFUNCTION(ApiListener, &ApiListener::StatsFunc); @@ -90,7 +91,9 @@ void ApiListener::OnConfigLoaded(void) void ApiListener::OnAllConfigLoaded(void) { - if (!Endpoint::GetByName(GetIdentity())) + m_LocalEndpoint = Endpoint::GetByName(GetIdentity()); + + if (!m_LocalEndpoint) BOOST_THROW_EXCEPTION(ScriptError("Endpoint object for '" + GetIdentity() + "' is missing.", GetDebugInfo())); } @@ -101,11 +104,10 @@ void ApiListener::Start(bool runtimeCreated) { SyncZoneDirs(); - if (std::distance(ConfigType::GetObjectsByType().first, - ConfigType::GetObjectsByType().second) > 1) { - Log(LogCritical, "ApiListener", "Only one ApiListener object is allowed."); - return; - } + if (m_Instance) + BOOST_THROW_EXCEPTION(ScriptError("Only one ApiListener object is allowed.", GetDebugInfo())); + + m_Instance = this; ObjectImpl::Start(runtimeCreated); @@ -133,10 +135,7 @@ void ApiListener::Start(bool runtimeCreated) ApiListener::Ptr ApiListener::GetInstance(void) { - BOOST_FOREACH(const ApiListener::Ptr& listener, ConfigType::GetObjectsByType()) - return listener; - - return ApiListener::Ptr(); + return m_Instance; } boost::shared_ptr ApiListener::GetSSLContext(void) const @@ -169,7 +168,7 @@ bool ApiListener::IsMaster(void) const if (!master) return false; - return master->GetName() == GetIdentity(); + return master == GetLocalEndpoint(); } /** @@ -417,7 +416,7 @@ void ApiListener::ApiTimerHandler(void) bool need = false; BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType()) { - if (endpoint->GetName() == GetIdentity()) + if (endpoint == GetLocalEndpoint()) continue; if (endpoint->GetLogDuration() >= 0 && ts < now - endpoint->GetLogDuration()) @@ -454,7 +453,7 @@ void ApiListener::ApiTimerHandler(void) BOOST_FOREACH(const Endpoint::Ptr& endpoint, zone->GetEndpoints()) { /* don't connect to ourselves */ - if (endpoint->GetName() == GetIdentity()) { + if (endpoint == GetLocalEndpoint()) { Log(LogDebug, "ApiListener") << "Not connecting to Endpoint '" << endpoint->GetName() << "' because that's us."; continue; @@ -601,7 +600,7 @@ void ApiListener::SyncRelayMessage(const MessageOrigin::Ptr& origin, BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType()) { /* don't relay messages to ourselves */ - if (endpoint->GetName() == GetIdentity()) + if (endpoint == GetLocalEndpoint()) continue; Zone::Ptr target_zone = endpoint->GetZone(); @@ -1029,3 +1028,8 @@ Value ApiListener::HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dicti { return Empty; } + +Endpoint::Ptr ApiListener::GetLocalEndpoint(void) const +{ + return m_LocalEndpoint; +} diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 9cf8278f3..e9d91464f 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -59,6 +59,8 @@ public: Endpoint::Ptr GetMaster(void) const; bool IsMaster(void) const; + Endpoint::Ptr GetLocalEndpoint(void) const; + static String GetApiDir(void); void SyncSendMessage(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message); @@ -97,6 +99,9 @@ private: std::set m_AnonymousClients; std::set m_HttpClients; Timer::Ptr m_Timer; + Endpoint::Ptr m_LocalEndpoint; + + static ApiListener::Ptr m_Instance; void ApiTimerHandler(void); diff --git a/lib/remote/endpoint.cpp b/lib/remote/endpoint.cpp index fc8c98642..4d7464f9e 100644 --- a/lib/remote/endpoint.cpp +++ b/lib/remote/endpoint.cpp @@ -122,5 +122,5 @@ Endpoint::Ptr Endpoint::GetLocalEndpoint(void) if (!listener) return Endpoint::Ptr(); - return Endpoint::GetByName(listener->GetIdentity()); + return listener->GetLocalEndpoint(); } diff --git a/lib/remote/zone.cpp b/lib/remote/zone.cpp index 1a307c91d..b9538d522 100644 --- a/lib/remote/zone.cpp +++ b/lib/remote/zone.cpp @@ -27,9 +27,14 @@ using namespace icinga; REGISTER_TYPE(Zone); +void Zone::OnAllConfigLoaded(void) +{ + m_Parent = Zone::GetByName(GetParentRaw()); +} + Zone::Ptr Zone::GetParent(void) const { - return Zone::GetByName(GetParentRaw()); + return m_Parent; } std::set Zone::GetEndpoints(void) const @@ -61,7 +66,7 @@ bool Zone::CanAccessObject(const ConfigObject::Ptr& object) if (dynamic_pointer_cast(object)) object_zone = static_pointer_cast(object); else - object_zone = Zone::GetByName(object->GetZoneName()); + object_zone = static_pointer_cast(object->GetZone()); if (!object_zone) object_zone = Zone::GetLocalZone(); diff --git a/lib/remote/zone.hpp b/lib/remote/zone.hpp index 9092e26fa..5738aa789 100644 --- a/lib/remote/zone.hpp +++ b/lib/remote/zone.hpp @@ -36,6 +36,8 @@ public: DECLARE_OBJECT(Zone); DECLARE_OBJECTNAME(Zone); + virtual void OnAllConfigLoaded(void) override; + Zone::Ptr GetParent(void) const; std::set GetEndpoints(void) const; @@ -44,6 +46,9 @@ public: bool IsGlobal(void) const; static Zone::Ptr GetLocalZone(void); + +private: + Zone::Ptr m_Parent; }; }