From b367187c0b4b89cb4537486f7ea011d7557c9331 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 9 May 2014 13:02:30 +0200 Subject: [PATCH] Implement HA for IDO connections. Refs #6107 --- components/db_ido_mysql/idomysqlconnection.cpp | 12 ++++++++---- components/db_ido_mysql/idomysqlconnection.h | 4 ++-- components/db_ido_pgsql/idopgsqlconnection.cpp | 12 ++++++++---- components/db_ido_pgsql/idopgsqlconnection.h | 4 ++-- lib/base/dynamicobject.cpp | 6 +++++- lib/base/dynamicobject.ti | 4 +++- lib/db_ido/dbconnection.cpp | 18 ++++++++++++++++++ lib/db_ido/dbconnection.h | 2 ++ lib/remote/authority.cpp | 5 +---- 9 files changed, 49 insertions(+), 18 deletions(-) diff --git a/components/db_ido_mysql/idomysqlconnection.cpp b/components/db_ido_mysql/idomysqlconnection.cpp index 5ee21c274..5d05bca72 100644 --- a/components/db_ido_mysql/idomysqlconnection.cpp +++ b/components/db_ido_mysql/idomysqlconnection.cpp @@ -60,16 +60,16 @@ Value IdoMysqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe return 0; } -void IdoMysqlConnection::Start(void) +void IdoMysqlConnection::Resume(void) { - DbConnection::Start(); + DbConnection::Resume(); m_Connected = false; m_QueryQueue.SetExceptionCallback(boost::bind(&IdoMysqlConnection::ExceptionHandler, this, _1)); m_TxTimer = make_shared(); - m_TxTimer->SetInterval(5); + m_TxTimer->SetInterval(1); m_TxTimer->OnTimerExpired.connect(boost::bind(&IdoMysqlConnection::TxTimerHandler, this)); m_TxTimer->Start(); @@ -82,8 +82,12 @@ void IdoMysqlConnection::Start(void) ASSERT(mysql_thread_safe()); } -void IdoMysqlConnection::Stop(void) +void IdoMysqlConnection::Pause(void) { + DbConnection::Pause(); + + m_ReconnectTimer.reset(); + m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::Disconnect, this)); m_QueryQueue.Join(); } diff --git a/components/db_ido_mysql/idomysqlconnection.h b/components/db_ido_mysql/idomysqlconnection.h index 4d778df39..26c03974c 100644 --- a/components/db_ido_mysql/idomysqlconnection.h +++ b/components/db_ido_mysql/idomysqlconnection.h @@ -45,8 +45,8 @@ public: static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); protected: - virtual void Start(void); - virtual void Stop(void); + virtual void Resume(void); + virtual void Pause(void); virtual void ActivateObject(const DbObject::Ptr& dbobj); virtual void DeactivateObject(const DbObject::Ptr& dbobj); diff --git a/components/db_ido_pgsql/idopgsqlconnection.cpp b/components/db_ido_pgsql/idopgsqlconnection.cpp index d549d8a9c..f00dd250e 100644 --- a/components/db_ido_pgsql/idopgsqlconnection.cpp +++ b/components/db_ido_pgsql/idopgsqlconnection.cpp @@ -62,16 +62,16 @@ Value IdoPgsqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe return 0; } -void IdoPgsqlConnection::Start(void) +void IdoPgsqlConnection::Resume(void) { - DbConnection::Start(); + DbConnection::Resume(); m_Connection = NULL; m_QueryQueue.SetExceptionCallback(boost::bind(&IdoPgsqlConnection::ExceptionHandler, this, _1)); m_TxTimer = make_shared(); - m_TxTimer->SetInterval(5); + m_TxTimer->SetInterval(1); m_TxTimer->OnTimerExpired.connect(boost::bind(&IdoPgsqlConnection::TxTimerHandler, this)); m_TxTimer->Start(); @@ -84,8 +84,12 @@ void IdoPgsqlConnection::Start(void) ASSERT(PQisthreadsafe()); } -void IdoPgsqlConnection::Stop(void) +void IdoPgsqlConnection::Pause(void) { + DbConnection::Pause(); + + m_ReconnectTimer.reset(); + m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::Disconnect, this)); m_QueryQueue.Join(); } diff --git a/components/db_ido_pgsql/idopgsqlconnection.h b/components/db_ido_pgsql/idopgsqlconnection.h index a30d3bec3..e0459d4cc 100644 --- a/components/db_ido_pgsql/idopgsqlconnection.h +++ b/components/db_ido_pgsql/idopgsqlconnection.h @@ -45,8 +45,8 @@ public: static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); protected: - virtual void Start(void); - virtual void Stop(void); + virtual void Resume(void); + virtual void Pause(void); virtual void ActivateObject(const DbObject::Ptr& dbobj); virtual void DeactivateObject(const DbObject::Ptr& dbobj); diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index 5b58dc77b..f7eec1d7e 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -140,6 +140,8 @@ void DynamicObject::Activate(void) } OnStarted(GetSelf()); + + SetAuthority(true); } void DynamicObject::Stop(void) @@ -154,6 +156,8 @@ void DynamicObject::Deactivate(void) { ASSERT(!OwnsLock()); + SetAuthority(false); + { ObjectLock olock(this); @@ -200,7 +204,7 @@ void DynamicObject::SetAuthority(bool authority) OnResumed(GetSelf()); } else if (!authority && !GetPaused()) { SetPauseCalled(false); - Resume(); + Pause(); ASSERT(GetPauseCalled()); SetPaused(true); OnPaused(GetSelf()); diff --git a/lib/base/dynamicobject.ti b/lib/base/dynamicobject.ti index 1a7939cce..b887d0b9b 100644 --- a/lib/base/dynamicobject.ti +++ b/lib/base/dynamicobject.ti @@ -25,7 +25,9 @@ abstract class DynamicObject [config] Dictionary::Ptr methods; [config] Dictionary::Ptr vars (VarsRaw); [get_protected] bool active; - [get_protected] bool paused; + [get_protected] bool paused { + default {{{ return true; }}} + }; [get_protected] bool start_called; [get_protected] bool stop_called; [get_protected] bool pause_called; diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp index c06eebd10..e6f75d7ae 100644 --- a/lib/db_ido/dbconnection.cpp +++ b/lib/db_ido/dbconnection.cpp @@ -43,6 +43,13 @@ void DbConnection::Start(void) DynamicObject::Start(); DbObject::OnQuery.connect(boost::bind(&DbConnection::ExecuteQuery, this, _1)); +} + +void DbConnection::Resume(void) +{ + DynamicObject::Resume(); + + Log(LogInformation, "db_ido", "Resuming IDO connection: " + GetName()); m_CleanUpTimer = make_shared(); m_CleanUpTimer->SetInterval(60); @@ -50,6 +57,17 @@ void DbConnection::Start(void) m_CleanUpTimer->Start(); } +void DbConnection::Pause(void) +{ + DynamicObject::Pause(); + + Log(LogInformation, "db_ido", "Pausing IDO connection: " + GetName()); + + m_CleanUpTimer.reset(); + + ClearIDCache(); +} + void DbConnection::StaticInitialize(void) { m_ProgramStatusTimer = make_shared(); diff --git a/lib/db_ido/dbconnection.h b/lib/db_ido/dbconnection.h index d5af98558..ffb15a2aa 100644 --- a/lib/db_ido/dbconnection.h +++ b/lib/db_ido/dbconnection.h @@ -65,6 +65,8 @@ public: protected: virtual void Start(void); + virtual void Resume(void); + virtual void Pause(void); virtual void ExecuteQuery(const DbQuery& query) = 0; virtual void ActivateObject(const DbObject::Ptr& dbobj) = 0; diff --git a/lib/remote/authority.cpp b/lib/remote/authority.cpp index 12d8dc4ff..3a3fa6574 100644 --- a/lib/remote/authority.cpp +++ b/lib/remote/authority.cpp @@ -61,10 +61,7 @@ static void AuthorityTimerHandler(void) BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) { Endpoint::Ptr endpoint = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()]; - if (endpoint == my_endpoint) - object->Resume(); - else - object->Pause(); + object->SetAuthority(endpoint == my_endpoint); } } }