AccountState: Add a 1-5min reconnection delay #5872
authorChristian Kamm <mail@ckamm.de>
Tue, 4 Jul 2017 10:23:23 +0000 (12:23 +0200)
committerMarkus Goetz <markus@woboq.com>
Tue, 4 Jul 2017 11:12:41 +0000 (13:12 +0200)
This only applies when the server was explicitly in maintenance mode or
when it was 503-unavailable.

src/gui/accountstate.cpp
src/gui/accountstate.h

index e7ed89bc29ca9d7f9af0eac41b8947116342af50..d2025dde18be683af6aabd91e2e18b4a5d8997cb 100644 (file)
@@ -20,6 +20,7 @@
 #include "configfile.h"
 
 #include <QSettings>
+#include <QTimer>
 #include <qfontmetrics.h>
 
 namespace OCC {
@@ -32,6 +33,7 @@ AccountState::AccountState(AccountPtr account)
     , _state(AccountState::Disconnected)
     , _connectionStatus(ConnectionValidator::Undefined)
     , _waitingForNewCredentials(false)
+    , _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay
 {
     qRegisterMetaType<AccountState *>("AccountState*");
 
@@ -228,6 +230,23 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
         return;
     }
 
+    // Come online gradually from 503 or maintenance mode
+    if (status == ConnectionValidator::Connected
+        && (_connectionStatus == ConnectionValidator::ServiceUnavailable
+               || _connectionStatus == ConnectionValidator::MaintenanceMode)) {
+        if (!_timeSinceMaintenanceOver.isValid()) {
+            qCInfo(lcAccountState) << "AccountState reconnection: delaying for"
+                                   << _maintenanceToConnectedDelay << "ms";
+            _timeSinceMaintenanceOver.start();
+            QTimer::singleShot(_maintenanceToConnectedDelay + 100, this, SLOT(checkConnectivity()));
+            return;
+        } else if (_timeSinceMaintenanceOver.elapsed() < _maintenanceToConnectedDelay) {
+            qCInfo(lcAccountState) << "AccountState reconnection: only"
+                                   << _timeSinceMaintenanceOver.elapsed() << "ms have passed";
+            return;
+        }
+    }
+
     if (_connectionStatus != status) {
         qCInfo(lcAccountState) << "AccountState connection status change: "
                                << connectionStatusString(_connectionStatus) << "->"
@@ -263,9 +282,11 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
         setState(SignedOut);
         break;
     case ConnectionValidator::ServiceUnavailable:
+        _timeSinceMaintenanceOver.invalidate();
         setState(ServiceUnavailable);
         break;
     case ConnectionValidator::MaintenanceMode:
+        _timeSinceMaintenanceOver.invalidate();
         setState(MaintenanceMode);
         break;
     case ConnectionValidator::Timeout:
index 450766bf8244fd29d54ab372bf2331db04e677b1..2333bcece8e370d2da9dcd4bc76aa95bb8a310ce 100644 (file)
@@ -107,10 +107,6 @@ public:
 
     bool isConnected() const;
 
-    /// Triggers a ping to the server to update state and
-    /// connection status and errors.
-    void checkConnectivity();
-
     /** Returns a new settings object for this account, already in the right groups. */
     std::unique_ptr<QSettings> settings();
 
@@ -127,6 +123,11 @@ public:
      */
     void tagLastSuccessfullETagRequest();
 
+public slots:
+    /// Triggers a ping to the server to update state and
+    /// connection status and errors.
+    void checkConnectivity();
+
 private:
     void setState(State state);
 
@@ -148,6 +149,18 @@ private:
     bool _waitingForNewCredentials;
     QElapsedTimer _timeSinceLastETagCheck;
     QPointer<ConnectionValidator> _connectionValidator;
+
+    /**
+     * Starts counting when the server starts being back up after 503 or
+     * maintenance mode. The account will only become connected once this
+     * timer exceeds the _maintenanceToConnectedDelay value.
+     */
+    QElapsedTimer _timeSinceMaintenanceOver;
+
+    /**
+     * Milliseconds for which to delay reconnection after 503/maintenance.
+     */
+    int _maintenanceToConnectedDelay;
 };
 }