Detect maintenance mode #4485
authorChristian Kamm <mail@ckamm.de>
Mon, 8 May 2017 10:39:08 +0000 (12:39 +0200)
committerMarkus Goetz <markus@woboq.com>
Thu, 11 May 2017 09:39:49 +0000 (11:39 +0200)
When we first detect a 503 (probably from a PROPFIND) and enter the
ServiceUnavailable state, we new trigger a status.php query that will
switch the state to MaintenanceMode if necessary.

src/gui/accountsettings.cpp
src/gui/accountstate.cpp
src/gui/accountstate.h
src/libsync/connectionvalidator.cpp
src/libsync/connectionvalidator.h

index 92b451520f6dfd0e3dc3fca630c1a4bcf6001019..a82dbdbf993487df4d554d54604c3e5096d25896 100644 (file)
@@ -601,6 +601,8 @@ void AccountSettings::slotAccountStateChanged(int state)
             showConnectionLabel( tr("Connected to %1.").arg(serverWithUser), errors );
         } else if (state == AccountState::ServiceUnavailable) {
             showConnectionLabel( tr("Server %1 is temporarily unavailable.").arg(server) );
+        } else if (state == AccountState::MaintenanceMode) {
+            showConnectionLabel( tr("Server %1 is currently in maintenance mode.").arg(server) );
         } else if (state == AccountState::SignedOut) {
             showConnectionLabel( tr("Signed out from %1.").arg(serverWithUser) );
         } else {
index fb2dc5360fed02980a6aa17b3918f0f897aa4640..b92b0ae441edc111e765f2ac2da4e368453dd4f9 100644 (file)
@@ -94,6 +94,14 @@ void AccountState::setState(State state)
             _connectionStatus = ConnectionValidator::Undefined;
             _connectionErrors.clear();
         } else if (oldState == SignedOut && _state == Disconnected) {
+            // If we stop being voluntarily signed-out, try to connect and
+            // auth right now!
+            checkConnectivity();
+        } else if (_state == ServiceUnavailable) {
+            // Check if we are actually down for maintenance.
+            // To do this we must clear the connection validator that just
+            // produced the 503. It's finished anyway and will delete itself.
+            _connectionValidator.clear();
             checkConnectivity();
         }
         if (oldState == Connected || _state == Connected) {
@@ -117,6 +125,8 @@ QString AccountState::stateString(State state)
         return tr("Connected");
     case ServiceUnavailable:
         return tr("Service unavailable");
+    case MaintenanceMode:
+        return tr("Maintenance mode");
     case NetworkError:
         return tr("Network error");
     case ConfigurationError:
@@ -148,11 +158,6 @@ bool AccountState::isConnected() const
     return _state == Connected;
 }
 
-bool AccountState::isConnectedOrTemporarilyUnavailable() const
-{
-    return isConnected() || _state == ServiceUnavailable;
-}
-
 void AccountState::tagLastSuccessfullETagRequest()
 {
     _timeSinceLastETagCheck.restart();
@@ -252,6 +257,9 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
     case ConnectionValidator::ServiceUnavailable:
         setState(ServiceUnavailable);
         break;
+    case ConnectionValidator::MaintenanceMode:
+        setState(MaintenanceMode);
+        break;
     case ConnectionValidator::Timeout:
         setState(NetworkError);
         break;
index ed7f0337631f4df4da82fde203e0efaa4d40f386..ef81bb39ff7c5512fe900aed1a1c3de81bee1e8c 100644 (file)
@@ -54,6 +54,10 @@ public:
         /// don't bother the user too much and try again.
         ServiceUnavailable,
 
+        /// Similar to ServiceUnavailable, but we know the server is down
+        /// for maintenance
+        MaintenanceMode,
+
         /// Could not communicate with the server for some reason.
         /// We assume this may resolve itself over time and will try
         /// again automatically.
@@ -101,7 +105,6 @@ public:
     void signIn();
 
     bool isConnected() const;
-    bool isConnectedOrTemporarilyUnavailable() const;
 
     /// Triggers a ping to the server to update state and
     /// connection status and errors.
index 76945baf254c5fc7009d4328274127475bf79cc8..e102243c2035b9e8b77aa2083f52fbf8c46ab5e1 100644 (file)
@@ -55,6 +55,8 @@ QString ConnectionValidator::statusString( Status stat )
         return QLatin1String("User canceled credentials");
     case ServiceUnavailable:
         return QLatin1String("Service unavailable");
+    case MaintenanceMode:
+        return QLatin1String("Maintenance mode");
     case Timeout:
         return QLatin1String("Timeout");
     }
@@ -130,6 +132,11 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QJsonObject &inf
         return;
     }
 
+    if (info["maintenance"].toBool()) {
+        reportResult( MaintenanceMode );
+        return;
+    }
+
     // now check the authentication
     if (_account->credentials()->ready())
         QTimer::singleShot( 0, this, SLOT( checkAuthentication() ));
index 0bebbeb4974aa1eb48baa0e39324a782b1cfc301..e4e729701ae5d1fdcdffb728f5b8bbfcd8deb4d9 100644 (file)
@@ -85,13 +85,13 @@ public:
         Undefined,
         Connected,
         NotConfigured,
-        ServerVersionMismatch,
-        CredentialsMissingOrWrong,
-        StatusNotFound,
-        UserCanceledCredentials,
-        ServiceUnavailable,
-        // actually also used for other errors on the authed request
-        Timeout
+        ServerVersionMismatch, // The server version is too old
+        CredentialsMissingOrWrong, // Credentials aren't ready or AuthenticationRequiredError
+        StatusNotFound, // Error retrieving status.php
+        UserCanceledCredentials, // checkAuthentication when credentials aren't ready
+        ServiceUnavailable, // 503 on authed request
+        MaintenanceMode, // maintenance enabled in status.php
+        Timeout // actually also used for other errors on the authed request
     };
 
     static QString statusString( Status );