From: Michael Friedrich Date: Sun, 7 Oct 2012 19:47:50 +0000 (+0200) Subject: Compat IDO: add reconnect to ido2db, if not connected (refs #3207) X-Git-Tag: v0.0.1~39 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d42dd6e03f28dd350347c8c9756b78df6363a504;p=icinga2 Compat IDO: add reconnect to ido2db, if not connected (refs #3207) --- diff --git a/components/compatido/compatidocomponent.cpp b/components/compatido/compatidocomponent.cpp index f4294f4a5..a3ff9f367 100644 --- a/components/compatido/compatidocomponent.cpp +++ b/components/compatido/compatidocomponent.cpp @@ -24,6 +24,8 @@ using namespace icinga; const String CompatIdoComponent::DefaultSocketAddress = "127.0.0.1"; const String CompatIdoComponent::DefaultSocketPort = "5668"; const String CompatIdoComponent::DefaultInstanceName = "i2-default"; +const int CompatIdoComponent::DefaultReconnectInterval = 15; + /** * Reads the socket address from the config @@ -65,6 +67,19 @@ String CompatIdoComponent::GetInstanceName(void) const return instance; } +/** + * Reads the reconnect interval from the config + * @returns reconnect_interval The config option, or static default + */ +int CompatIdoComponent::GetReconnectInterval(void) const +{ + Value interval = GetConfig()->Get("reconnect_interval"); + if(interval.IsEmpty()) + return DefaultReconnectInterval; + else + return interval; +} + /** * Starts the component. */ @@ -73,6 +88,7 @@ void CompatIdoComponent::Start(void) const int StatusTimerInterval = 60; const int ConfigTimerInterval = 3600; const int ProgramStatusTimerInterval = 15; + const int ReconnectTimerInterval = GetReconnectInterval(); /* HINTS - XXX * - only tcp sockets @@ -97,22 +113,59 @@ void CompatIdoComponent::Start(void) m_ProgramStatusTimer->Start(); m_ProgramStatusTimer->Reschedule(0); + /* + * scheck for reconnect once in a while + */ + m_ReconnectTimer = boost::make_shared(); + m_ReconnectTimer->SetInterval(ReconnectTimerInterval); + m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&CompatIdoComponent::ReconnectTimerHandler, this)); + m_ReconnectTimer->Start(); /* * open ido socket once */ - OpenSink(GetSocketAddress(), GetSocketPort()); - SendHello(GetInstanceName()); + OpenIdoSocket(); } + /** * Stops the component. */ void CompatIdoComponent::Stop(void) +{ + CloseIdoSocket(); +} + + +/** + * Opens the ido socket, and sends hello to ido2db + */ +void CompatIdoComponent::OpenIdoSocket(void) +{ + OpenSink(GetSocketAddress(), GetSocketPort()); + + /* + * if we're connected, do not reconnecte + */ + if(m_IdoSocket->IsConnected()) { + m_IdoSocket->SetReconnect(false); + + /* connected means we can greet ido2db */ + SendHello(GetInstanceName()); + } else { + m_IdoSocket->SetReconnect(true); + } +} + +/* + * Sends goodbye to ido2db, and closes ido socket + */ +void CompatIdoComponent::CloseIdoSocket(void) { GoodByeSink(); CloseSink(); } + /* TODO * subscribe to all status updates and checkresults and dump them * should remove the periodic statusdata dump @@ -150,6 +203,34 @@ void CompatIdoComponent::ProgramStatusTimerHandler(void) DumpProgramStatusData(); } +/** + * Periodically check if idosocket requires a reconnect + */ +void CompatIdoComponent::ReconnectTimerHandler(void) +{ + Logger::Write(LogInformation, "compatido", "Checking if ido socket requires reconnect"); + + if(m_IdoSocket->GetReconnect()) { + + /* check if we aren't already connected */ + if(m_IdoSocket->IsConnected()) { + Logger::Write(LogInformation, "compatido", "Already connected to ido socket ... no reconnect necessary."); + return; + } + + /* socket was disconnected, recconnect */ + OpenIdoSocket(); + + if(m_IdoSocket->IsConnected()) { + Logger::Write(LogInformation, "compatido", "Successfully reconnected to ido socket"); + } else { + stringstream message; + message << "Unable to reconnect to ido socket. Trying again in " << GetReconnectInterval() << " sec."; + Logger::Write(LogWarning, "compatido", message.str()); + } + } +} + /** * opens a tcp connection to the ido socket diff --git a/components/compatido/compatidocomponent.h b/components/compatido/compatidocomponent.h index 4a3fd3345..148d01475 100644 --- a/components/compatido/compatidocomponent.h +++ b/components/compatido/compatidocomponent.h @@ -36,17 +36,24 @@ private: Timer::Ptr m_StatusTimer; Timer::Ptr m_ConfigTimer; Timer::Ptr m_ProgramStatusTimer; + Timer::Ptr m_ReconnectTimer; + IdoSocket::Ptr m_IdoSocket; String GetSocketAddress(void) const; String GetSocketPort(void) const; String GetInstanceName(void) const; + int GetReconnectInterval(void) const; void ConfigTimerHandler(void); void StatusTimerHandler(void); void ProgramStatusTimerHandler(void); + void ReconnectTimerHandler(void); + + void OpenIdoSocket(void); + void CloseIdoSocket(void); - void OpenSink(String node, String service ); + void OpenSink(String node, String service); void SendHello(String instancename); void GoodByeSink(void); void CloseSink(void); @@ -78,6 +85,8 @@ private: static const String DefaultSocketAddress; static const String DefaultSocketPort; static const String DefaultInstanceName; + static const int DefaultReconnectInterval; + }; } diff --git a/components/compatido/idosocket.cpp b/components/compatido/idosocket.cpp index 6e8102a7c..b028f2da0 100644 --- a/components/compatido/idosocket.cpp +++ b/components/compatido/idosocket.cpp @@ -36,6 +36,12 @@ IdoSocket::IdoSocket(TcpClientRole role) * signal telling about new data */ OnDataAvailable.connect(boost::bind(&IdoSocket::DataAvailableHandler, this)); + + /* + * what to do on disconnect + */ + OnClosed.connect(boost::bind(&IdoSocket::ClientClosedHandler, this)); + } /** @@ -53,6 +59,49 @@ void IdoSocket::SendMessage(const String& message) Write(message.CStr(), message.GetLength()); } + +/** + * Handles closed client connect + */ +void IdoSocket::ClientClosedHandler(void) +{ + try { + CheckException(); + } catch (const exception& ex) { + stringstream message; + message << "Error occured for ido socket: " << ex.what(); + + Logger::Write(LogWarning, "compatido", message.str()); + } + + Logger::Write(LogWarning, "compatido", "Lost connection to ido socket"); + + SetReconnect(true); + + OnDisconnected(GetSelf()); +} + + +/** + * Set reconnect vstate + * + * @aparam enable Enables the reconnect. + */ +void IdoSocket::SetReconnect(bool reconnect) +{ + m_Reconnect = reconnect; +} + +/** + * Get reconnect state + * + * @returns reconnect The reconnect variable + */ +bool IdoSocket::GetReconnect(void) +{ + return m_Reconnect; +} + /** * Processes inbound data. * Currently not used, as we do not receive data from ido sockets diff --git a/components/compatido/idosocket.h b/components/compatido/idosocket.h index 890518cfd..498677bf5 100644 --- a/components/compatido/idosocket.h +++ b/components/compatido/idosocket.h @@ -39,11 +39,19 @@ public: IdoSocket(TcpClientRole role); void SendMessage(const String& message); + void SetReconnect(bool reconnect); + bool GetReconnect(void); boost::signal OnNewMessage; + boost::signal OnConnected; + boost::signal OnDisconnected; + private: void DataAvailableHandler(void); + void ClientClosedHandler(void); + + bool m_Reconnect; friend IdoSocket::Ptr IdoSocketFactory(SOCKET fd, TcpClientRole role); };