Only activate HARunOnce objects once there's a cluster connection

fixes #11765
This commit is contained in:
Gunnar Beutner 2016-05-11 12:50:08 +02:00
parent a529725a92
commit fc1168ed3e
6 changed files with 63 additions and 20 deletions

View File

@ -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;

View File

@ -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

View File

@ -396,7 +396,8 @@ void ConfigObject::Activate(bool runtimeCreated)
SetActive(true, true);
}
SetAuthority(true);
if (GetHAMode() == HARunEverywhere)
SetAuthority(true);
NotifyActive();
}

View File

@ -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::vector<std::strin
sigaction(SIGHUP, &sa, NULL);
#endif /* _WIN32 */
/* update object authority */
ApiListener::UpdateObjectAuthorityAsync();
return Application::GetInstance()->Run();
}

View File

@ -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;

View File

@ -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<Endpoint::Ptr> 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();
}