Compat IDO: add reconnect to ido2db, if not connected (refs #3207)

This commit is contained in:
Michael Friedrich 2012-10-07 21:47:50 +02:00
parent 7c45e460e6
commit d42dd6e03f
4 changed files with 150 additions and 3 deletions

View File

@ -24,6 +24,8 @@ using namespace icinga;
const String CompatIdoComponent::DefaultSocketAddress = "127.0.0.1"; const String CompatIdoComponent::DefaultSocketAddress = "127.0.0.1";
const String CompatIdoComponent::DefaultSocketPort = "5668"; const String CompatIdoComponent::DefaultSocketPort = "5668";
const String CompatIdoComponent::DefaultInstanceName = "i2-default"; const String CompatIdoComponent::DefaultInstanceName = "i2-default";
const int CompatIdoComponent::DefaultReconnectInterval = 15;
/** /**
* Reads the socket address from the config * Reads the socket address from the config
@ -65,6 +67,19 @@ String CompatIdoComponent::GetInstanceName(void) const
return instance; 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. * Starts the component.
*/ */
@ -73,6 +88,7 @@ void CompatIdoComponent::Start(void)
const int StatusTimerInterval = 60; const int StatusTimerInterval = 60;
const int ConfigTimerInterval = 3600; const int ConfigTimerInterval = 3600;
const int ProgramStatusTimerInterval = 15; const int ProgramStatusTimerInterval = 15;
const int ReconnectTimerInterval = GetReconnectInterval();
/* HINTS - XXX /* HINTS - XXX
* - only tcp sockets * - only tcp sockets
@ -97,22 +113,59 @@ void CompatIdoComponent::Start(void)
m_ProgramStatusTimer->Start(); m_ProgramStatusTimer->Start();
m_ProgramStatusTimer->Reschedule(0); m_ProgramStatusTimer->Reschedule(0);
/*
* scheck for reconnect once in a while
*/
m_ReconnectTimer = boost::make_shared<Timer>();
m_ReconnectTimer->SetInterval(ReconnectTimerInterval);
m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&CompatIdoComponent::ReconnectTimerHandler, this));
m_ReconnectTimer->Start();
/* /*
* open ido socket once * open ido socket once
*/ */
OpenSink(GetSocketAddress(), GetSocketPort()); OpenIdoSocket();
SendHello(GetInstanceName());
} }
/** /**
* Stops the component. * Stops the component.
*/ */
void CompatIdoComponent::Stop(void) 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(); GoodByeSink();
CloseSink(); CloseSink();
} }
/* TODO /* TODO
* subscribe to all status updates and checkresults and dump them * subscribe to all status updates and checkresults and dump them
* should remove the periodic statusdata dump * should remove the periodic statusdata dump
@ -150,6 +203,34 @@ void CompatIdoComponent::ProgramStatusTimerHandler(void)
DumpProgramStatusData(); 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 * opens a tcp connection to the ido socket

View File

@ -36,17 +36,24 @@ private:
Timer::Ptr m_StatusTimer; Timer::Ptr m_StatusTimer;
Timer::Ptr m_ConfigTimer; Timer::Ptr m_ConfigTimer;
Timer::Ptr m_ProgramStatusTimer; Timer::Ptr m_ProgramStatusTimer;
Timer::Ptr m_ReconnectTimer;
IdoSocket::Ptr m_IdoSocket; IdoSocket::Ptr m_IdoSocket;
String GetSocketAddress(void) const; String GetSocketAddress(void) const;
String GetSocketPort(void) const; String GetSocketPort(void) const;
String GetInstanceName(void) const; String GetInstanceName(void) const;
int GetReconnectInterval(void) const;
void ConfigTimerHandler(void); void ConfigTimerHandler(void);
void StatusTimerHandler(void); void StatusTimerHandler(void);
void ProgramStatusTimerHandler(void); void ProgramStatusTimerHandler(void);
void ReconnectTimerHandler(void);
void OpenSink(String node, String service ); void OpenIdoSocket(void);
void CloseIdoSocket(void);
void OpenSink(String node, String service);
void SendHello(String instancename); void SendHello(String instancename);
void GoodByeSink(void); void GoodByeSink(void);
void CloseSink(void); void CloseSink(void);
@ -78,6 +85,8 @@ private:
static const String DefaultSocketAddress; static const String DefaultSocketAddress;
static const String DefaultSocketPort; static const String DefaultSocketPort;
static const String DefaultInstanceName; static const String DefaultInstanceName;
static const int DefaultReconnectInterval;
}; };
} }

View File

@ -36,6 +36,12 @@ IdoSocket::IdoSocket(TcpClientRole role)
* signal telling about new data * signal telling about new data
*/ */
OnDataAvailable.connect(boost::bind(&IdoSocket::DataAvailableHandler, this)); 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()); 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. * Processes inbound data.
* Currently not used, as we do not receive data from ido sockets * Currently not used, as we do not receive data from ido sockets

View File

@ -39,11 +39,19 @@ public:
IdoSocket(TcpClientRole role); IdoSocket(TcpClientRole role);
void SendMessage(const String& message); void SendMessage(const String& message);
void SetReconnect(bool reconnect);
bool GetReconnect(void);
boost::signal<void (const IdoSocket::Ptr&, const stringstream&)> OnNewMessage; boost::signal<void (const IdoSocket::Ptr&, const stringstream&)> OnNewMessage;
boost::signal<void (const IdoSocket::Ptr&)> OnConnected;
boost::signal<void (const IdoSocket::Ptr&)> OnDisconnected;
private: private:
void DataAvailableHandler(void); void DataAvailableHandler(void);
void ClientClosedHandler(void);
bool m_Reconnect;
friend IdoSocket::Ptr IdoSocketFactory(SOCKET fd, TcpClientRole role); friend IdoSocket::Ptr IdoSocketFactory(SOCKET fd, TcpClientRole role);
}; };