From fc1168ed3e1f587fb16f4d616895c054495644b3 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 11 May 2016 12:50:08 +0200 Subject: [PATCH] Only activate HARunOnce objects once there's a cluster connection fixes #11765 --- lib/base/application.cpp | 13 +++++++++ lib/base/application.hpp | 4 +++ lib/base/configobject.cpp | 3 +- lib/cli/daemoncommand.cpp | 4 +++ lib/remote/apilistener.hpp | 3 ++ lib/remote/authority.cpp | 56 +++++++++++++++++++++++++------------- 6 files changed, 63 insertions(+), 20 deletions(-) diff --git a/lib/base/application.cpp b/lib/base/application.cpp index b0cdc1286..c9e2c7c33 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -60,6 +60,7 @@ static bool l_InExceptionHandler = false; int Application::m_ArgC; char **Application::m_ArgV; double Application::m_StartTime; +double Application::m_MainTime; bool Application::m_ScriptDebuggerEnabled = false; /** @@ -885,6 +886,8 @@ int Application::Run(void) return EXIT_FAILURE; } + SetMainTime(Utility::GetTime()); + return Main(); } @@ -1364,6 +1367,16 @@ void Application::SetStartTime(double ts) m_StartTime = ts; } +double Application::GetMainTime(void) +{ + return m_MainTime; +} + +void Application::SetMainTime(double ts) +{ + m_MainTime = ts; +} + bool Application::GetScriptDebuggerEnabled(void) { return m_ScriptDebuggerEnabled; diff --git a/lib/base/application.hpp b/lib/base/application.hpp index d030eb2a7..2174d3e03 100644 --- a/lib/base/application.hpp +++ b/lib/base/application.hpp @@ -134,6 +134,9 @@ public: static double GetStartTime(void); static void SetStartTime(double ts); + static double GetMainTime(void); + static void SetMainTime(double ts); + static bool GetScriptDebuggerEnabled(void); static void SetScriptDebuggerEnabled(bool enabled); @@ -167,6 +170,7 @@ private: static bool m_Debugging; /**< Whether debugging is enabled. */ static LogSeverity m_DebuggingSeverity; /**< Whether debugging severity is set. */ static double m_StartTime; + static double m_MainTime; static bool m_ScriptDebuggerEnabled; #ifndef _WIN32 diff --git a/lib/base/configobject.cpp b/lib/base/configobject.cpp index cfb099480..1cb6e3f3c 100644 --- a/lib/base/configobject.cpp +++ b/lib/base/configobject.cpp @@ -396,7 +396,8 @@ void ConfigObject::Activate(bool runtimeCreated) SetActive(true, true); } - SetAuthority(true); + if (GetHAMode() == HARunEverywhere) + SetAuthority(true); NotifyActive(); } diff --git a/lib/cli/daemoncommand.cpp b/lib/cli/daemoncommand.cpp index f650af3a4..be32b22d6 100644 --- a/lib/cli/daemoncommand.cpp +++ b/lib/cli/daemoncommand.cpp @@ -19,6 +19,7 @@ #include "cli/daemoncommand.hpp" #include "cli/daemonutility.hpp" +#include "remote/apilistener.hpp" #include "config/configcompiler.hpp" #include "config/configcompilercontext.hpp" #include "config/configitembuilder.hpp" @@ -302,5 +303,8 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vectorRun(); } diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 4c860f89b..d4cb5e540 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -97,6 +97,9 @@ public: static Value ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); + + static void UpdateObjectAuthorityAsync(void); + protected: virtual void OnConfigLoaded(void) override; virtual void OnAllConfigLoaded(void) override; diff --git a/lib/remote/authority.cpp b/lib/remote/authority.cpp index 37a244ee4..cb81fa927 100644 --- a/lib/remote/authority.cpp +++ b/lib/remote/authority.cpp @@ -36,42 +36,60 @@ static bool ObjectNameLessComparer(const ConfigObject::Ptr& a, const ConfigObjec static void AuthorityTimerHandler(void) { - ApiListener::Ptr listener = ApiListener::GetInstance(); - - if (!listener || !listener->IsActive()) - return; - Zone::Ptr my_zone = Zone::GetLocalZone(); - if (!my_zone) - return; - - Endpoint::Ptr my_endpoint = Endpoint::GetLocalEndpoint(); std::vector endpoints; - BOOST_FOREACH(const Endpoint::Ptr& endpoint, my_zone->GetEndpoints()) { - if (!endpoint->GetConnected() && endpoint != my_endpoint) - continue; + Endpoint::Ptr my_endpoint; - endpoints.push_back(endpoint); + if (my_zone) { + my_endpoint = Endpoint::GetLocalEndpoint(); + + int num_total = 0; + + BOOST_FOREACH(const Endpoint::Ptr& endpoint, my_zone->GetEndpoints()) { + num_total++; + + if (endpoint != my_endpoint && !endpoint->GetConnected()) + continue; + + endpoints.push_back(endpoint); + } + + double mainTime = Application::GetMainTime(); + + if (num_total > 1 && endpoints.size() <= 1 && (mainTime == 0 || Utility::GetTime() - mainTime < 60)) + return; + + std::sort(endpoints.begin(), endpoints.end(), ObjectNameLessComparer); } - std::sort(endpoints.begin(), endpoints.end(), ObjectNameLessComparer); - BOOST_FOREACH(const ConfigType::Ptr& type, ConfigType::GetTypes()) { BOOST_FOREACH(const ConfigObject::Ptr& object, type->GetObjects()) { - Endpoint::Ptr endpoint = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()]; + if (object->GetHAMode() != HARunOnce) + continue; - if (object->GetHAMode() == HARunOnce) - object->SetAuthority(endpoint == my_endpoint); + bool authority; + + if (!my_zone) + authority = true; + else + authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; + + object->SetAuthority(authority); } } } +void ApiListener::UpdateObjectAuthorityAsync(void) +{ + l_AuthorityTimer->Reschedule(0); +} + static void StaticInitialize(void) { l_AuthorityTimer = new Timer(); l_AuthorityTimer->OnTimerExpired.connect(boost::bind(&AuthorityTimerHandler)); - l_AuthorityTimer->SetInterval(30); + l_AuthorityTimer->SetInterval(15); l_AuthorityTimer->Start(); }