[Libreoffice-commits] online.git: loolwsd/DocumentBroker.cpp loolwsd/DocumentBroker.hpp loolwsd/LOOLWSD.cpp loolwsd/MasterProcessSession.cpp loolwsd/MasterProcessSession.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Sun Apr 10 03:37:25 UTC 2016


 loolwsd/DocumentBroker.cpp       |   37 +++++++++++++++++++++++++++
 loolwsd/DocumentBroker.hpp       |   13 +++++++++
 loolwsd/LOOLWSD.cpp              |   52 ++++++---------------------------------
 loolwsd/MasterProcessSession.cpp |    1 
 loolwsd/MasterProcessSession.hpp |    1 
 5 files changed, 59 insertions(+), 45 deletions(-)

New commits:
commit e6d0882791fbf1b25b6d63e86f65c1f5224f2c4a
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Apr 9 23:20:20 2016 -0400

    loolwsd: moved autosave to DocumentBroker
    
    Autosaving is done by DocumentBroker, which
    tracks the last save time.
    
    There are two triggers: idle and auto save.
    The first triggers when sufficient time passes
    after the last interaction the user had with
    the UI (currently 30 seconds).
    The second triggers when it's been more than
    5 minutes since the last save.
    Both triggers are conditional on the user
    being active after the last save.
    
    The new code auto-saves doesn't issue
    a save command per session, but only
    one per doc.
    
    Change-Id: Iada15c16002e70710d2c13a3dcfdab036d8935c6
    Reviewed-on: https://gerrit.libreoffice.org/23951
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index aee583d..862b298 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -70,6 +70,7 @@ DocumentBroker::DocumentBroker(const Poco::URI& uriPublic,
     _docKey(docKey),
     _childRoot(childRoot),
     _cacheRoot(getCachePath(uriPublic.toString())),
+    _lastSaveTime(std::chrono::steady_clock::now()),
     _childProcess(childProcess),
     _sessionsCount(0)
 {
@@ -135,6 +136,7 @@ bool DocumentBroker::save()
     assert(_storage && _tileCache);
     if (_storage->saveLocalFileToStorage())
     {
+        _lastSaveTime = std::chrono::steady_clock::now();
         _tileCache->documentSaved();
         return true;
     }
@@ -142,6 +144,41 @@ bool DocumentBroker::save()
     return false;
 }
 
+void DocumentBroker::autoSave()
+{
+    std::unique_lock<std::mutex> sessionsLock(_wsSessionsMutex);
+    if (_wsSessions.empty())
+    {
+        // Shouldn't happen.
+        return;
+    }
+
+    // Find the most recent activity.
+    double inactivityTimeMs = std::numeric_limits<double>::max();
+    for (auto& sessionIt: _wsSessions)
+    {
+        inactivityTimeMs = std::min(sessionIt.second->getInactivityMS(), inactivityTimeMs);
+    }
+
+    Log::trace("Most recent inactivity was " + std::to_string(inactivityTimeMs) + " ms ago.");
+    const auto timeSinceLastSaveMs = getTimeSinceLastSaveMs();
+    Log::trace("Time since last save was " + std::to_string(timeSinceLastSaveMs) + " ms ago.");
+
+    // There has been some editing since we saved last?
+    if (inactivityTimeMs < timeSinceLastSaveMs)
+    {
+        // Either we've been idle long enough, or it's auto-save time.
+        if (inactivityTimeMs >= IdleSaveDurationMs ||
+            timeSinceLastSaveMs >= AutoSaveDurationMs)
+        {
+            Log::info("Auto-save triggered for doc [" + _docKey + "].");
+
+            // Any session can be used to save.
+            _wsSessions.begin()->second->getQueue()->put("uno .uno:Save");
+        }
+    }
+}
+
 std::string DocumentBroker::getJailRoot() const
 {
     assert(!_jailId.empty());
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index 7dedb64..66e2497 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -131,6 +131,8 @@ public:
 
     bool save();
 
+    void autoSave();
+
     Poco::URI getPublicUri() const { return _uriPublic; }
     Poco::URI getJailedUri() const { return _uriJailed; }
     const std::string& getJailId() const { return _jailId; }
@@ -140,6 +142,13 @@ public:
     unsigned getSessionsCount() { return _sessionsCount; }
     TileCache& tileCache() { return *_tileCache; }
 
+    /// Returns the time in milliseconds since last save.
+    double getTimeSinceLastSaveMs() const
+    {
+        const auto duration = (std::chrono::steady_clock::now() - _lastSaveTime);
+        return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
+    }
+
     std::string getJailRoot() const;
 
     /// Ignore input events from all web socket sessions
@@ -164,11 +173,15 @@ private:
     Poco::URI _uriJailed;
     std::string _jailId;
     std::string _filename;
+    std::chrono::steady_clock::time_point _lastSaveTime;
     std::unique_ptr<StorageBase> _storage;
     std::unique_ptr<TileCache> _tileCache;
     std::shared_ptr<ChildProcess> _childProcess;
     std::mutex _mutex;
     std::atomic<unsigned> _sessionsCount;
+
+    static constexpr auto IdleSaveDurationMs = 30 * 1000;
+    static constexpr auto AutoSaveDurationMs = 300 * 1000;
 };
 
 #endif
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index a1a3b2a..9e32cbd 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -511,9 +511,6 @@ private:
                 }
                 else
                 {
-                    // Keep track of timestamps of incoming client messages that indicate editing
-                    if (tokenIndicatesUserInteraction(token))
-                        time(&session->_lastUserInteractionTime);
                     queue->put(payload);
                 }
 
@@ -1419,7 +1416,6 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
     preForkChildren();
 
     time_t last30SecCheck = time(NULL);
-    time_t lastFiveMinuteCheck = last30SecCheck;
 
     int status = 0;
     while (!TerminationFlag && !LOOLWSD::DoTest)
@@ -1486,54 +1482,24 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
         {
             if (!std::getenv("LOOL_NO_AUTOSAVE"))
             {
-                time_t now = time(NULL);
-                if (now >= last30SecCheck + 30)
+                if (time(nullptr) >= last30SecCheck + 30)
                 {
                     Log::trace("30-second check");
-                    last30SecCheck = now;
 
-                    std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
-                    for (auto& brokerIt : docBrokers)
+                    try
                     {
-                        std::unique_lock<std::mutex> sessionsLock(brokerIt.second->_wsSessionsMutex);
-                        for (auto& sessionIt: brokerIt.second->_wsSessions)
+                        std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
+                        for (auto& brokerIt : docBrokers)
                         {
-                            // If no editing done by the client since we last did an idle save,
-                            // and it is more than 30 seconds since the last edit, do an idle save.
-                            if (sessionIt.second->_lastUserInteractionTime > sessionIt.second->_idleSaveTime &&
-                                sessionIt.second->_lastUserInteractionTime < now - 30)
-                            {
-                                Log::info("Idle save triggered for session " + sessionIt.second->getId());
-                                sessionIt.second->getQueue()->put("uno .uno:Save");
-
-                                sessionIt.second->_idleSaveTime = now;
-                            }
+                            brokerIt.second->autoSave();
                         }
                     }
-                }
-                if (now >= lastFiveMinuteCheck + 300)
-                {
-                    Log::trace("Five-minute check");
-                    lastFiveMinuteCheck = now;
-
-                    std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
-                    for (auto& brokerIt : docBrokers)
+                    catch (const std::exception& exc)
                     {
-                        std::unique_lock<std::mutex> sessionsLock(brokerIt.second->_wsSessionsMutex);
-                        for (auto& sessionIt: brokerIt.second->_wsSessions)
-                        {
-                            // If some editing by from the client since we last did an (idle or
-                            // auto) save, do an auto save.
-                            if (sessionIt.second->_lastUserInteractionTime >= sessionIt.second->_idleSaveTime &&
-                                sessionIt.second->_lastUserInteractionTime >= sessionIt.second->_autoSaveTime)
-                            {
-                                Log::info("Auto-save triggered for session " + sessionIt.second->getId());
-                                sessionIt.second->getQueue()->put("uno .uno:Save");
-
-                                sessionIt.second->_autoSaveTime = now;
-                            }
-                        }
+                        Log::error("Exception: " + std::string(exc.what()));
                     }
+
+                    last30SecCheck = time(nullptr);
                 }
             }
             sleep(MAINTENANCE_INTERVAL*2);
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index f9ad626..8339ab1 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -39,7 +39,6 @@ MasterProcessSession::MasterProcessSession(const std::string& id,
                                            std::shared_ptr<DocumentBroker> docBroker,
                                            std::shared_ptr<BasicTileQueue> queue) :
     LOOLSession(id, kind, ws),
-    _lastUserInteractionTime(0),
     _idleSaveTime(0),
     _autoSaveTime(0),
     _curPart(0),
diff --git a/loolwsd/MasterProcessSession.hpp b/loolwsd/MasterProcessSession.hpp
index c5b962c..f2b5d22 100644
--- a/loolwsd/MasterProcessSession.hpp
+++ b/loolwsd/MasterProcessSession.hpp
@@ -60,7 +60,6 @@ public:
     static std::mutex AvailableChildSessionMutex;
     static std::condition_variable AvailableChildSessionCV;
 
-    time_t _lastUserInteractionTime;
     time_t _idleSaveTime;
     time_t _autoSaveTime;
 


More information about the Libreoffice-commits mailing list