[Libreoffice-commits] online.git: loolwsd/ChildProcessSession.cpp loolwsd/ChildProcessSession.hpp loolwsd/LOOLKit.cpp loolwsd/MasterProcessSession.cpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Sun Jan 24 13:15:15 PST 2016


 loolwsd/ChildProcessSession.cpp  |   28 ++++++++++++++++++++++++++++
 loolwsd/ChildProcessSession.hpp  |   31 +++++++++++++++++++++++++++++++
 loolwsd/LOOLKit.cpp              |   13 +++++++++++--
 loolwsd/MasterProcessSession.cpp |    1 -
 4 files changed, 70 insertions(+), 3 deletions(-)

New commits:
commit 904bf929f19084d3b71be758bfdde89d1c55d8ac
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Jan 24 15:24:11 2016 -0500

    loolwsd: throttle traffic for inactive sessions
    
    Sessions that have been inactive for a certain duration,
    currently set at 120 seconds, will not receive updates.
    
    A new statistics class tracks the activity of every
    session and blocks callback updates from reaching
    inactive clients.
    
    Change-Id: I64296488b2c0be0598b218ba89a6d02f057a5f7e
    Reviewed-on: https://gerrit.libreoffice.org/21760
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index 5edc7b5..e89eb82 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -90,6 +90,34 @@ bool ChildProcessSession::handleDisconnect(Poco::StringTokenizer& tokens)
 
 bool ChildProcessSession::_handleInput(const char *buffer, int length)
 {
+    if (isInactive() && _loKitDocument != nullptr)
+    {
+        Log::debug("Handling message after inactivity of " + std::to_string(_stats.getInactivityMS()) + "ms.");
+
+        // Client is getting active again.
+        // Send invalidation and other sync-up messages.
+        std::unique_lock<std::recursive_mutex> lock(Mutex);
+
+        if (_multiView)
+            _loKitDocument->pClass->setView(_loKitDocument, _viewId);
+
+        int curPart = _loKitDocument->pClass->getPart(_loKitDocument);
+        sendTextFrame("curpart: part=" + std::to_string(curPart));
+        if (getDocType() == "text")
+        {
+            curPart = 0;
+        }
+
+        sendTextFrame("invalidatetiles:"
+                       " part=" + std::to_string(curPart) +
+                       " x=0 y=0"
+                       " width=" + std::to_string(INT_MAX) +
+                       " height=" + std::to_string(INT_MAX));
+
+        //TODO: Sync cursor.
+    }
+
+    _stats.updateLastActivityTime();
     const std::string firstLine = getFirstLine(buffer, length);
     StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
 
diff --git a/loolwsd/ChildProcessSession.hpp b/loolwsd/ChildProcessSession.hpp
index 6d9f326..f0b47b3 100644
--- a/loolwsd/ChildProcessSession.hpp
+++ b/loolwsd/ChildProcessSession.hpp
@@ -24,6 +24,30 @@ static int ClientPortNumber = DEFAULT_CLIENT_PORT_NUMBER;
 class ChildProcessSession final : public LOOLSession
 {
 public:
+    class Statistics
+    {
+    public:
+        Statistics() :
+            _lastActivityTime(std::chrono::steady_clock::now())
+        {
+        }
+
+        void updateLastActivityTime()
+        {
+            _lastActivityTime = std::chrono::steady_clock::now();
+        }
+
+        double getInactivityMS() const
+        {
+            const auto duration = (std::chrono::steady_clock::now() - _lastActivityTime);
+            return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
+        }
+
+    private:
+        std::chrono::steady_clock::time_point _lastActivityTime;
+    };
+
+public:
     /// Create a new ChildProcessSession
     /// ws The socket between master and kit (jailed).
     /// loKit The LOKit instance.
@@ -57,6 +81,9 @@ public:
 
     std::unique_lock<std::recursive_mutex> getLock() { return std::unique_lock<std::recursive_mutex>(Mutex); }
 
+    const Statistics& getStatistics() const { return _stats; }
+    bool isInactive() const { return _stats.getInactivityMS() >= InactivityThresholdMS; }
+
  protected:
     virtual bool loadDocument(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
 
@@ -96,10 +123,14 @@ private:
     int _clientPart;
     std::function<LibreOfficeKitDocument*(const std::string&, const std::string&)> _onLoad;
     std::function<void(const std::string&)> _onUnload;
+    /// Statistics and activity tracking.
+    Statistics _stats;
 
     /// Synchronize _loKitDocument acess.
     /// This should be inside LoKit.
     static std::recursive_mutex Mutex;
+
+    static constexpr auto InactivityThresholdMS = 120 * 1000;
 };
 
 #endif
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 67966ef..f542ec2 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -144,6 +144,16 @@ public:
         Log::trace() << "Callback [" << pSession->getViewId() << "] "
                      << callbackTypeToString(nType)
                      << " [" << rPayload << "]." << Log::end;
+        if (pSession->isDisconnected())
+        {
+            Log::trace("Skipping callback on disconnected session " + pSession->getName());
+            return;
+        }
+        else if (pSession->isInactive())
+        {
+            Log::trace("Skipping callback on inactive session " + pSession->getName());
+            return;
+        }
 
         switch (static_cast<LibreOfficeKitCallbackType>(nType))
         {
@@ -424,8 +434,7 @@ public:
             queue.put("eof");
             queueHandlerThread.join();
 
-            _session->sendTextFrame("disconnect");
-            _session->sendTextFrame("eof");
+            _session->disconnect();
         }
         catch (const Exception& exc)
         {
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 8c101c2..15fb1f4 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -88,7 +88,6 @@ bool MasterProcessSession::handleDisconnect(Poco::StringTokenizer& tokens)
               "].");
 
     LOOLSession::handleDisconnect(tokens);
-    disconnect(tokens.count() > 1 ? tokens[1] : std::string());
 
     auto peer = _peer.lock();
     if (peer)


More information about the Libreoffice-commits mailing list