From 7b673a0d57c1e6604088d1d5642945c386facf4b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 25 Dec 2010 12:02:14 +0530 Subject: [PATCH] Implemented auto-reconnect for portgroups --- client/mainwindow.cpp | 2 -- client/portgroup.cpp | 32 ++++++++++++++++++++++++++++++++ client/portgroup.h | 13 ++++++++++--- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp index 291865f..623624f 100644 --- a/client/mainwindow.cpp +++ b/client/mainwindow.cpp @@ -56,8 +56,6 @@ MainWindow::MainWindow(QWidget *parent) localServer_ = new QProcess(this); localServer_->setProcessChannelMode(QProcess::ForwardedChannels); localServer_->start(serverApp, QStringList()); - // TODO: waitForReadyRead() is a kludge till we implement auto-retry! - localServer_->waitForReadyRead(1000); pgl = new PortGroupList; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index faa1f0a..43e68a3 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -27,6 +27,7 @@ along with this program. If not, see #include #include #include +#include #include using ::google::protobuf::NewCallback; @@ -46,6 +47,13 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) statsController = new PbRpcController(portIdList_, portStatsList_); isGetStatsPending_ = false; + reconnect = false; + reconnectAfter = kMinReconnectWaitTime; + reconnectTimer = new QTimer(this); + reconnectTimer->setSingleShot(true); + connect(reconnectTimer, SIGNAL(timeout()), + this, SLOT(on_reconnectTimer_timeout())); + rpcChannel = new PbRpcChannel(ip, port); serviceStub = new OstProto::OstService::Stub(rpcChannel); @@ -75,6 +83,15 @@ PortGroup::~PortGroup() // ------------------------------------------------ // Slots // ------------------------------------------------ +void PortGroup::on_reconnectTimer_timeout() +{ + reconnectAfter *= 2; + if (reconnectAfter > kMaxReconnectWaitTime) + reconnectAfter = kMaxReconnectWaitTime; + + connectToHost(); +} + void PortGroup::on_rpcChannel_stateChanged(QAbstractSocket::SocketState state) { qDebug("state changed %d", state); @@ -98,6 +115,8 @@ void PortGroup::on_rpcChannel_connected() qDebug("connected\n"); emit portGroupDataChanged(mPortGroupId); + reconnectAfter = kMinReconnectWaitTime; + qDebug("requesting portlist ..."); PbRpcController *controller = new PbRpcController(void_, portIdList); @@ -115,12 +134,25 @@ void PortGroup::on_rpcChannel_disconnected() emit portListChanged(mPortGroupId); emit portGroupDataChanged(mPortGroupId); + + if (reconnect) + { + qDebug("starting reconnect timer for %d ms ...", reconnectAfter); + reconnectTimer->start(reconnectAfter); + } } void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { qDebug("%s: error %d", __FUNCTION__, socketError); emit portGroupDataChanged(mPortGroupId); + + qDebug("%s: state %d", __FUNCTION__, rpcChannel->state()); + if ((rpcChannel->state() == QAbstractSocket::UnconnectedState) && reconnect) + { + qDebug("starting reconnect timer for %d ms...", reconnectAfter); + reconnectTimer->start(reconnectAfter); + } } void PortGroup::processPortIdList(PbRpcController *controller) diff --git a/client/portgroup.h b/client/portgroup.h index dbf831c..8261576 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -37,6 +37,7 @@ LOW #define DEFAULT_SERVER_PORT 7878 class QFile; +class QTimer; class PortGroup : public QObject { Q_OBJECT @@ -46,6 +47,11 @@ private: quint32 mPortGroupId; QString mUserAlias; // user defined + bool reconnect; + int reconnectAfter; // time in milliseconds + static const int kMinReconnectWaitTime = 2000; // ms + static const int kMaxReconnectWaitTime = 60000; // ms + QTimer *reconnectTimer; PbRpcChannel *rpcChannel; PbRpcController *statsController; bool isGetStatsPending_; @@ -63,10 +69,10 @@ public: quint16 port = DEFAULT_SERVER_PORT); ~PortGroup(); - void connectToHost() { rpcChannel->establish(); } + void connectToHost() { reconnect = true; rpcChannel->establish(); } void connectToHost(QHostAddress ip, quint16 port) - { rpcChannel->establish(ip, port); } - void disconnectFromHost() { rpcChannel->tearDown(); } + { reconnect = true; rpcChannel->establish(ip, port); } + void disconnectFromHost() { reconnect = false; rpcChannel->tearDown(); } int numPorts() const { return mPorts.size(); } quint32 id() const { return mPortGroupId; } @@ -123,6 +129,7 @@ signals: void statsChanged(quint32 portGroupId); private slots: + void on_reconnectTimer_timeout(); void on_rpcChannel_stateChanged(QAbstractSocket::SocketState state); void on_rpcChannel_connected(); void on_rpcChannel_disconnected();