Fix reconnection logic in the client
authorManuel Nickschas <sputnick@quassel-irc.org>
Thu, 27 Feb 2014 20:10:40 +0000 (21:10 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Thu, 27 Feb 2014 20:17:08 +0000 (21:17 +0100)
Seems like b654b2f broke reconnecting the client to the core; it would
only try once and then stop trying. Thanks to mamarley for noticing that bug
and bisecting the culprit.

The main issue causing this was that CoreConnection called
resetConnection(false) before (re)connecting, thus clearing the reconnect
flag. This call is a remnant from before we refactored out all the socket
handling and should not be needed anymore, now that we have clean disconnected()
semantics. Before b654b2f this was not a problem, because we would always
receive a socket error on failed reconnect that would reinstate the flag.

Because b654b2f worked around another issue by always sending a disconnected()
when the socket goes back into UnconnectedState, and this would happen before
the socket error signal was sent, the error handling would never be called
and the reconnect flag thus not reinstated, causing this bug.

So the second fix is to spin the event loop such that the error signal can
overtake that disconnected() signal and be handled properly (so we also
get the socket error message in the status bar).

src/client/clientauthhandler.cpp
src/client/coreconnection.cpp

index 0d24a76..9440419 100644 (file)
@@ -114,7 +114,9 @@ void ClientAuthHandler::onSocketStateChanged(QAbstractSocket::SocketState socket
                 text = tr("Disconnected");
                 // Ensure the disconnected() signal is sent even if we haven't reached the Connected state yet.
                 // The baseclass implementation will make sure to only send the signal once.
                 text = tr("Disconnected");
                 // Ensure the disconnected() signal is sent even if we haven't reached the Connected state yet.
                 // The baseclass implementation will make sure to only send the signal once.
-                onSocketDisconnected();
+                // However, we do want to prefer a potential socket error signal that may be on route already, so
+                // give this a chance to overtake us by spinning the loop...
+                QTimer::singleShot(0, this, SLOT(onSocketDisconnected()));
             }
             break;
         default:
             }
             break;
         default:
index db18ef4..3650385 100644 (file)
@@ -378,8 +378,6 @@ void CoreConnection::connectToCurrentAccount()
         return;
     }
 
         return;
     }
 
-    resetConnection(false);
-
     if (currentAccount().isInternal()) {
         if (Quassel::runMode() != Quassel::Monolithic) {
             qWarning() << "Cannot connect to internal core in client-only mode!";
     if (currentAccount().isInternal()) {
         if (Quassel::runMode() != Quassel::Monolithic) {
             qWarning() << "Cannot connect to internal core in client-only mode!";