Improve performance for Zone::CanAccessObject

fixes #10711
This commit is contained in:
Michael Friedrich 2015-11-24 15:25:55 +01:00 committed by Gunnar Beutner
parent 9dc37c58ea
commit eda28b219d
7 changed files with 46 additions and 18 deletions

View File

@ -440,7 +440,7 @@ void ConfigObject::OnConfigLoaded(void)
void ConfigObject::OnAllConfigLoaded(void) void ConfigObject::OnAllConfigLoaded(void)
{ {
/* Nothing to do here. */ m_Zone = GetObject("Zone", GetZoneName());
} }
void ConfigObject::CreateChildObjects(const Type::Ptr& childType) 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 ConfigObject::Ptr();
return dtype->GetObject(name); return dtype->GetObject(name);
} }
ConfigObject::Ptr ConfigObject::GetZone(void) const
{
return m_Zone;
}

View File

@ -53,6 +53,8 @@ public:
Value GetExtension(const String& key); Value GetExtension(const String& key);
void ClearExtension(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 ModifyAttribute(const String& attr, const Value& value, bool updateVersion = true);
void RestoreAttribute(const String& attr, bool updateVersion = true); void RestoreAttribute(const String& attr, bool updateVersion = true);
bool IsAttributeModified(const String& attr) const; bool IsAttributeModified(const String& attr) const;
@ -97,6 +99,8 @@ protected:
explicit ConfigObject(void); explicit ConfigObject(void);
private: private:
ConfigObject::Ptr m_Zone;
static void RestoreObject(const String& message, int attributeTypes); static void RestoreObject(const String& message, int attributeTypes);
}; };

View File

@ -41,6 +41,7 @@ using namespace icinga;
REGISTER_TYPE(ApiListener); REGISTER_TYPE(ApiListener);
boost::signals2::signal<void(bool)> ApiListener::OnMasterChanged; boost::signals2::signal<void(bool)> ApiListener::OnMasterChanged;
ApiListener::Ptr ApiListener::m_Instance;
REGISTER_STATSFUNCTION(ApiListener, &ApiListener::StatsFunc); REGISTER_STATSFUNCTION(ApiListener, &ApiListener::StatsFunc);
@ -90,7 +91,9 @@ void ApiListener::OnConfigLoaded(void)
void ApiListener::OnAllConfigLoaded(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())); BOOST_THROW_EXCEPTION(ScriptError("Endpoint object for '" + GetIdentity() + "' is missing.", GetDebugInfo()));
} }
@ -101,11 +104,10 @@ void ApiListener::Start(bool runtimeCreated)
{ {
SyncZoneDirs(); SyncZoneDirs();
if (std::distance(ConfigType::GetObjectsByType<ApiListener>().first, if (m_Instance)
ConfigType::GetObjectsByType<ApiListener>().second) > 1) { BOOST_THROW_EXCEPTION(ScriptError("Only one ApiListener object is allowed.", GetDebugInfo()));
Log(LogCritical, "ApiListener", "Only one ApiListener object is allowed.");
return; m_Instance = this;
}
ObjectImpl<ApiListener>::Start(runtimeCreated); ObjectImpl<ApiListener>::Start(runtimeCreated);
@ -133,10 +135,7 @@ void ApiListener::Start(bool runtimeCreated)
ApiListener::Ptr ApiListener::GetInstance(void) ApiListener::Ptr ApiListener::GetInstance(void)
{ {
BOOST_FOREACH(const ApiListener::Ptr& listener, ConfigType::GetObjectsByType<ApiListener>()) return m_Instance;
return listener;
return ApiListener::Ptr();
} }
boost::shared_ptr<SSL_CTX> ApiListener::GetSSLContext(void) const boost::shared_ptr<SSL_CTX> ApiListener::GetSSLContext(void) const
@ -169,7 +168,7 @@ bool ApiListener::IsMaster(void) const
if (!master) if (!master)
return false; return false;
return master->GetName() == GetIdentity(); return master == GetLocalEndpoint();
} }
/** /**
@ -417,7 +416,7 @@ void ApiListener::ApiTimerHandler(void)
bool need = false; bool need = false;
BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) { BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) {
if (endpoint->GetName() == GetIdentity()) if (endpoint == GetLocalEndpoint())
continue; continue;
if (endpoint->GetLogDuration() >= 0 && ts < now - endpoint->GetLogDuration()) if (endpoint->GetLogDuration() >= 0 && ts < now - endpoint->GetLogDuration())
@ -454,7 +453,7 @@ void ApiListener::ApiTimerHandler(void)
BOOST_FOREACH(const Endpoint::Ptr& endpoint, zone->GetEndpoints()) { BOOST_FOREACH(const Endpoint::Ptr& endpoint, zone->GetEndpoints()) {
/* don't connect to ourselves */ /* don't connect to ourselves */
if (endpoint->GetName() == GetIdentity()) { if (endpoint == GetLocalEndpoint()) {
Log(LogDebug, "ApiListener") Log(LogDebug, "ApiListener")
<< "Not connecting to Endpoint '" << endpoint->GetName() << "' because that's us."; << "Not connecting to Endpoint '" << endpoint->GetName() << "' because that's us.";
continue; continue;
@ -601,7 +600,7 @@ void ApiListener::SyncRelayMessage(const MessageOrigin::Ptr& origin,
BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) { BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) {
/* don't relay messages to ourselves */ /* don't relay messages to ourselves */
if (endpoint->GetName() == GetIdentity()) if (endpoint == GetLocalEndpoint())
continue; continue;
Zone::Ptr target_zone = endpoint->GetZone(); Zone::Ptr target_zone = endpoint->GetZone();
@ -1029,3 +1028,8 @@ Value ApiListener::HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dicti
{ {
return Empty; return Empty;
} }
Endpoint::Ptr ApiListener::GetLocalEndpoint(void) const
{
return m_LocalEndpoint;
}

View File

@ -59,6 +59,8 @@ public:
Endpoint::Ptr GetMaster(void) const; Endpoint::Ptr GetMaster(void) const;
bool IsMaster(void) const; bool IsMaster(void) const;
Endpoint::Ptr GetLocalEndpoint(void) const;
static String GetApiDir(void); static String GetApiDir(void);
void SyncSendMessage(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message); void SyncSendMessage(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message);
@ -97,6 +99,9 @@ private:
std::set<JsonRpcConnection::Ptr> m_AnonymousClients; std::set<JsonRpcConnection::Ptr> m_AnonymousClients;
std::set<HttpServerConnection::Ptr> m_HttpClients; std::set<HttpServerConnection::Ptr> m_HttpClients;
Timer::Ptr m_Timer; Timer::Ptr m_Timer;
Endpoint::Ptr m_LocalEndpoint;
static ApiListener::Ptr m_Instance;
void ApiTimerHandler(void); void ApiTimerHandler(void);

View File

@ -122,5 +122,5 @@ Endpoint::Ptr Endpoint::GetLocalEndpoint(void)
if (!listener) if (!listener)
return Endpoint::Ptr(); return Endpoint::Ptr();
return Endpoint::GetByName(listener->GetIdentity()); return listener->GetLocalEndpoint();
} }

View File

@ -27,9 +27,14 @@ using namespace icinga;
REGISTER_TYPE(Zone); REGISTER_TYPE(Zone);
void Zone::OnAllConfigLoaded(void)
{
m_Parent = Zone::GetByName(GetParentRaw());
}
Zone::Ptr Zone::GetParent(void) const Zone::Ptr Zone::GetParent(void) const
{ {
return Zone::GetByName(GetParentRaw()); return m_Parent;
} }
std::set<Endpoint::Ptr> Zone::GetEndpoints(void) const std::set<Endpoint::Ptr> Zone::GetEndpoints(void) const
@ -61,7 +66,7 @@ bool Zone::CanAccessObject(const ConfigObject::Ptr& object)
if (dynamic_pointer_cast<Zone>(object)) if (dynamic_pointer_cast<Zone>(object))
object_zone = static_pointer_cast<Zone>(object); object_zone = static_pointer_cast<Zone>(object);
else else
object_zone = Zone::GetByName(object->GetZoneName()); object_zone = static_pointer_cast<Zone>(object->GetZone());
if (!object_zone) if (!object_zone)
object_zone = Zone::GetLocalZone(); object_zone = Zone::GetLocalZone();

View File

@ -36,6 +36,8 @@ public:
DECLARE_OBJECT(Zone); DECLARE_OBJECT(Zone);
DECLARE_OBJECTNAME(Zone); DECLARE_OBJECTNAME(Zone);
virtual void OnAllConfigLoaded(void) override;
Zone::Ptr GetParent(void) const; Zone::Ptr GetParent(void) const;
std::set<Endpoint::Ptr> GetEndpoints(void) const; std::set<Endpoint::Ptr> GetEndpoints(void) const;
@ -44,6 +46,9 @@ public:
bool IsGlobal(void) const; bool IsGlobal(void) const;
static Zone::Ptr GetLocalZone(void); static Zone::Ptr GetLocalZone(void);
private:
Zone::Ptr m_Parent;
}; };
} }