[Libreoffice-commits] online.git: loleaflet/src wsd/LOOLWSD.cpp wsd/protocol.txt

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Nov 28 05:27:54 UTC 2016


 loleaflet/src/core/Socket.js |   30 ++++++++++++++++++++++++++++
 wsd/LOOLWSD.cpp              |   45 ++++++++++++++++++++++++++++++++++++++-----
 wsd/protocol.txt             |    4 ++-
 3 files changed, 73 insertions(+), 6 deletions(-)

New commits:
commit 2b9ea3d4a68e7483e837426bda178e489ae7a4b2
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Nov 27 19:11:30 2016 -0500

    loolwsd: notify clients before recycling wsd
    
    Change-Id: Ib2733a6af1c27fe39c54f5c3bc6f5bd3acb72a2b
    Reviewed-on: https://gerrit.libreoffice.org/31298
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index eab6ca8..40c4cf2 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -195,6 +195,36 @@ L.Socket = L.Class.extend({
 			else if (textMsg === 'shuttingdown') {
 				msg = _('Server is shutting down for maintenance (auto-saving)');
 			}
+			else if (textMsg === 'recycling') {
+				msg = _('Server is recycling and will be available shortly');
+
+				this._map._active = false;
+
+				// Prevent reconnecting the world at the same time.
+				var min = 5000;
+				var max = 10000;
+				var timeoutMs = Math.floor(Math.random() * (max - min) + min);
+
+				socket = this;
+				map = this._map;
+				vex.timer = setInterval(function() {
+					if (socket.connected()) {
+						// We're connected: cancel timer and dialog.
+						clearTimeout(vex.timer);
+						if (vex.dialogID > 0) {
+							var id = vex.dialogID;
+							vex.dialogID = -1;
+							vex.close(id);
+						}
+						return;
+					}
+
+					try {
+						socket.initialize(map);
+					} catch (error) {
+					}
+				}, timeoutMs);
+			}
 
 			// Close any open dialogs first.
 			if (vex.dialogID > 0) {
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 25a4bab..6b143a4 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -175,6 +175,10 @@ static std::atomic<int> OutstandingForks(1); // Forkit always spawns 1.
 static std::map<std::string, std::shared_ptr<DocumentBroker>> DocBrokers;
 static std::mutex DocBrokersMutex;
 
+/// Used when shutting down to notify them all that the server is recycling.
+static std::vector<std::shared_ptr<LOOLWebSocket>> ClientWebSockets;
+static std::mutex ClientWebSocketsMutex;
+
 #if ENABLE_DEBUG
 static int careerSpanSeconds = 0;
 #endif
@@ -983,6 +987,13 @@ private:
                 }
             }
 
+            if (SigUtil::isShuttingDown())
+            {
+                std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
+                LOG_TRC("Capturing Client WS for [" << id << "]");
+                ClientWebSockets.push_back(ws);
+            }
+
             LOOLWSD::dumpEventTrace(docBroker->getJailId(), id, "EndSession: " + uri);
             LOG_INF("Finishing GET request handler for session [" << id << "].");
         }
@@ -1011,11 +1022,14 @@ private:
         }
         else
         {
-            // something wrong, with internal exceptions
-            LOG_TRC("Abnormal close handshake.");
-            session->closeFrame();
-            // FIXME: handle exception thrown from here ? ...
-            ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
+            if (!SigUtil::isShuttingDown())
+            {
+                // something wrong, with internal exceptions
+                LOG_TRC("Abnormal close handshake.");
+                session->closeFrame();
+                // FIXME: handle exception thrown from here ? ...
+                ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
+            }
         }
 
         LOG_INF("Finished GET request handler for session [" << id << "].");
@@ -2149,6 +2163,27 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
         FileUtil::removeFile(path, true);
     }
 
+    if (SigUtil::isShuttingDown())
+    {
+        // At this point there should be no other thread, but...
+        std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
+
+        LOG_INF("Notifying clients that we are recycling.");
+        static const std::string msg("close: recycling");
+        for (auto& ws : ClientWebSockets)
+        {
+            try
+            {
+                ws->sendFrame(msg.data(), msg.size());
+                ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
+            }
+            catch (const std::exception& ex)
+            {
+                LOG_ERR("Error while notifying client of recycle: " << ex.what());
+            }
+        }
+    }
+
     // Finally, we no longer need SSL.
     if (LOOLWSD::isSSLEnabled())
     {
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index 2ebdc33..b6d55ef 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -248,11 +248,13 @@ close: <reason>
     ability to kill all other sessions if EnableOwnerTermination flag in WOPI
     CheckFileInfo is 'true' (assumed to be 'false' by default).
 
-
     * shuttingdown - Sent when the server is going down in a graceful fashion.
     The server doesn't disconnect from clients yet, but starts
     saving document and tearing down internals.
 
+    * recycling - The last message sent from the server when it is gracefully
+    shutting down to let clients know they can try connecting
+    after a short interval.
 
 getchildid: id=<id>
 


More information about the Libreoffice-commits mailing list