Ver código fonte

Connectivity: Improve reconnecting after network change/disconnect #4167

Markus Goetz 10 anos atrás
pai
commit
b52a3a415c

+ 16 - 1
src/gui/application.cpp

@@ -177,11 +177,15 @@ Application::Application(int &argc, char **argv) :
 
     // startup procedure.
     connect(&_checkConnectionTimer, SIGNAL(timeout()), this, SLOT(slotCheckConnection()));
-    _checkConnectionTimer.setInterval(32 * 1000); // check for connection every 32 seconds.
+    _checkConnectionTimer.setInterval(ConnectionValidator::defaultCallingIntervalMsec()); // check for connection every 32 seconds.
     _checkConnectionTimer.start();
     // Also check immediately
     QTimer::singleShot( 0, this, SLOT( slotCheckConnection() ));
 
+    // Can't use onlineStateChanged because it is always true on modern systems because of many interfaces
+    connect(&_networkConfigurationManager, SIGNAL(configurationChanged(QNetworkConfiguration)),
+                this, SLOT(slotSystemOnlineConfigurationChanged(QNetworkConfiguration)));
+
     // Update checks
     UpdaterScheduler *updaterScheduler = new UpdaterScheduler(this);
     connect(updaterScheduler, SIGNAL(updaterAnnouncement(QString, QString)),
@@ -234,6 +238,17 @@ void Application::slotCleanup()
     _gui->deleteLater();
 }
 
+// FIXME: This is not ideal yet since a ConnectionValidator might already be running and is in
+// progress of timing out in some seconds.
+// Maybe we need 2 validators, one triggered by timer, one by network configuration changes?
+void Application::slotSystemOnlineConfigurationChanged(QNetworkConfiguration cnf)
+{
+    if (cnf.state() & QNetworkConfiguration::Active) {
+        //qDebug() << "Trying fast reconnect";
+        QMetaObject::invokeMethod(this, "slotCheckConnection", Qt::QueuedConnection);
+    }
+}
+
 void Application::slotCheckConnection()
 {
     auto list = AccountManager::instance()->accounts();

+ 3 - 0
src/gui/application.h

@@ -20,6 +20,7 @@
 #include <QQueue>
 #include <QTimer>
 #include <QElapsedTimer>
+#include <QNetworkConfigurationManager>
 
 #include "qtsingleapplication.h"
 
@@ -87,6 +88,7 @@ protected slots:
     void slotAccountStateAdded(AccountState *accountState);
     void slotAccountStateRemoved(AccountState *accountState);
     void slotCrash();
+    void slotSystemOnlineConfigurationChanged(QNetworkConfiguration);
 
 private:
     void setHelp();
@@ -111,6 +113,7 @@ private:
 
     ClientProxy _proxy;
 
+    QNetworkConfigurationManager _networkConfigurationManager;
     QTimer _checkConnectionTimer;
 
 #if defined(WITH_CRASHREPORTER)

+ 2 - 0
src/libsync/abstractnetworkjob.h

@@ -57,6 +57,8 @@ public:
     QByteArray responseTimestamp();
     quint64 duration();
 
+    qint64 timeoutMsec() { return _timer.interval(); }
+
 public slots:
     void setTimeout(qint64 msec);
     void resetTimeout();

+ 6 - 0
src/libsync/connectionvalidator.cpp

@@ -23,6 +23,10 @@
 
 namespace OCC {
 
+// Make sure the timeout for this job is less than how often we get called
+// This makes sure we get tried often enough without "ConnectionValidator already running"
+static qint64 timeoutToUseMsec = qMax(qint64(1000), ConnectionValidator::defaultCallingIntervalMsec() - 5*1000);
+
 ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent)
     : QObject(parent),
       _account(account),
@@ -99,6 +103,7 @@ void ConnectionValidator::systemProxyLookupDone(const QNetworkProxy &proxy) {
 void ConnectionValidator::slotCheckServerAndAuth()
 {
     CheckServerJob *checkJob = new CheckServerJob(_account, this);
+    checkJob->setTimeout(timeoutToUseMsec);
     checkJob->setIgnoreCredentialFailure(true);
     connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
     connect(checkJob, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoStatusFound(QNetworkReply*)));
@@ -165,6 +170,7 @@ void ConnectionValidator::checkAuthentication()
     // continue in slotAuthCheck here :-)
     qDebug() << "# Check whether authenticated propfind works.";
     PropfindJob *job = new PropfindJob(_account, "/", this);
+    job->setTimeout(timeoutToUseMsec);
     job->setProperties(QList<QByteArray>() << "getlastmodified");
     connect(job, SIGNAL(result(QVariantMap)), SLOT(slotAuthSuccess()));
     connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));

+ 3 - 0
src/libsync/connectionvalidator.h

@@ -84,6 +84,9 @@ public:
 
     static QString statusString( Status );
 
+    // How often should the Application ask this object to check for the connection?
+    static qint64 defaultCallingIntervalMsec() { return 32 * 1000;}
+
 public slots:
     /// Checks the server and the authentication.
     void checkServerAndAuth();