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

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Mar 14 03:02:06 UTC 2016


 loolwsd/LOOLWSD.cpp              |   36 +++++++++++++++++++++++++++++++-----
 loolwsd/LOOLWSD.hpp              |   10 ++++++++--
 loolwsd/MasterProcessSession.cpp |    9 ++++++---
 loolwsd/MasterProcessSession.hpp |    6 +++++-
 loolwsd/test/httpwstest.cpp      |    2 +-
 5 files changed, 51 insertions(+), 12 deletions(-)

New commits:
commit f1007266e1644d3d7fde6149036646ec0f8198eb
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Thu Mar 10 22:33:03 2016 -0500

    loolwsd: DocumentStoreManager shared by MasterProcessSession instances
    
    Change-Id: Id7ada60387cafdf742690dbf345bb1e703b2ca76
    Reviewed-on: https://gerrit.libreoffice.org/23206
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 23cc2a1..2fcc86c 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -149,6 +149,8 @@ using Poco::Util::Option;
 using Poco::Util::OptionSet;
 using Poco::Util::ServerApplication;
 
+std::map<std::string, std::map<std::string, std::shared_ptr<MasterProcessSession>>> LOOLWSD::Sessions;
+std::mutex LOOLWSD::SessionsMutex;
 
 /// Handles the filename part of the convert-to POST request payload.
 class ConvertToPartHandler : public PartHandler
@@ -347,7 +349,7 @@ private:
                     // Load the document.
                     std::shared_ptr<WebSocket> ws;
                     const LOOLSession::Kind kind = LOOLSession::Kind::ToClient;
-                    auto session = std::make_shared<MasterProcessSession>(id, kind, ws);
+                    auto session = std::make_shared<MasterProcessSession>(id, kind, ws, nullptr);
                     const std::string filePrefix("file://");
                     std::string encodedFrom;
                     URI::encode(filePrefix + fromPath, "", encodedFrom);
@@ -495,7 +497,7 @@ private:
 
     void handleGetRequest(HTTPServerRequest& request, HTTPServerResponse& response, const std::string& id)
     {
-        Log::info("Starting Get request processor for session [" + id + "].");
+        Log::info("Starting GET request handler for session [" + id + "].");
 
         //TODO: Authenticate the caller.
         // authenticate(request, response);
@@ -503,8 +505,32 @@ private:
         // request.getCookies(cookies);
         // Log::info("Cookie: " + cookies.get("PHPSESSID", ""));
 
+        const auto uri = DocumentStoreManager::getUri(request.getURI());
+        const auto docKey = uri.getPath();
+
+        // This lock could become a bottleneck.
+        // In that case, we can use a pool and index by publicPath.
+        std::unique_lock<std::mutex> lock(LOOLWSD::SessionsMutex);
+
+        // Lookup this document.
+        auto it = LOOLWSD::Sessions.find(docKey);
+        std::shared_ptr<DocumentStoreManager> document;
+        if (it != LOOLWSD::Sessions.end())
+        {
+            // Get the DocumentStoreManager from the first session.
+            auto sessionsMap = it->second;
+            assert(!sessionsMap.empty());
+            document = sessionsMap.begin()->second->getDocumentStoreManager();
+        }
+        else
+        {
+            // Set up the document and its storage.
+            const auto jailRoot = Poco::Path(LOOLWSD::ChildRoot, id);
+            document = DocumentStoreManager::create(uri, jailRoot.toString(), id);
+        }
+
         auto ws = std::make_shared<WebSocket>(request, response);
-        auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToClient, ws);
+        auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToClient, ws, document);
 
         // For ToClient sessions, we store incoming messages in a queue and have a separate
         // thread that handles them. This is so that we can empty the queue when we get a
@@ -534,7 +560,7 @@ private:
                 }
             });
 
-        Log::info("Get request processor for session [" + id + "] finished. Clearing and joining the queue.");
+        Log::info("Finishing GET request handler for session [" + id + "]. Clearing and joining the queue.");
         queue.clear();
         queue.put("eof");
         queueHandlerThread.join();
@@ -607,7 +633,7 @@ public:
             Log::debug("Thread [" + thread_name + "] started.");
 
             auto ws = std::make_shared<WebSocket>(request, response);
-            auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToPrisoner, ws);
+            auto session = std::make_shared<MasterProcessSession>(id, LOOLSession::Kind::ToPrisoner, ws, nullptr);
 
             SocketProcessor(ws, response, [&session](const char* data, const int size, bool)
                 {
diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp
index e0120fe..e7ce8eb 100644
--- a/loolwsd/LOOLWSD.hpp
+++ b/loolwsd/LOOLWSD.hpp
@@ -24,6 +24,7 @@
 #include "Common.hpp"
 #include "Util.hpp"
 
+class MasterProcessSession;
 
 class LOOLWSD: public Poco::Util::ServerApplication
 {
@@ -31,8 +32,8 @@ public:
     LOOLWSD();
     ~LOOLWSD();
 
-    // An Application is a singleton anyway, so just keep these as
-    // statics
+    // An Application is a singleton anyway,
+    // so just keep these as statics.
     static std::atomic<unsigned> NextSessionId;
     static int NumPreSpawnedChildren;
     static int BrokerWritePipe;
@@ -50,6 +51,11 @@ public:
     static const std::string FIFO_LOOLWSD;
     static const std::string LOKIT_PIDLOG;
 
+    // All sessions for a given doc. The URI path (without host, port, or query) is the key.
+    // The value is a map of SessionId => Session instance.
+    static std::map<std::string, std::map<std::string, std::shared_ptr<MasterProcessSession>>> Sessions;
+    static std::mutex SessionsMutex;
+
     static
     std::string GenSessionId()
     {
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 307b1ae..7f052ac 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -32,10 +32,12 @@ std::condition_variable MasterProcessSession::AvailableChildSessionCV;
 
 MasterProcessSession::MasterProcessSession(const std::string& id,
                                            const Kind kind,
-                                           std::shared_ptr<Poco::Net::WebSocket> ws) :
+                                           std::shared_ptr<Poco::Net::WebSocket> ws,
+                                           std::shared_ptr<DocumentStoreManager> docStoreManager) :
     LOOLSession(id, kind, ws),
     _curPart(0),
-    _loadPart(-1)
+    _loadPart(-1),
+    _docStoreManager(docStoreManager)
 {
     Log::info("MasterProcessSession ctor [" + getName() + "].");
 }
@@ -394,7 +396,8 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
 
         if ((tokens.count() > 1 && tokens[0] == "uno" && tokens[1] == ".uno:Save"))
         {
-           _tileCache->documentSaved();
+            _docStoreManager->save();
+            _tileCache->documentSaved();
         }
         else if (tokens[0] == "disconnect")
         {
diff --git a/loolwsd/MasterProcessSession.hpp b/loolwsd/MasterProcessSession.hpp
index d6cceb0..1168651 100644
--- a/loolwsd/MasterProcessSession.hpp
+++ b/loolwsd/MasterProcessSession.hpp
@@ -21,7 +21,8 @@ class MasterProcessSession final : public LOOLSession, public std::enable_shared
 public:
     MasterProcessSession(const std::string& id,
                          const Kind kind,
-                         std::shared_ptr<Poco::Net::WebSocket> ws);
+                         std::shared_ptr<Poco::Net::WebSocket> ws,
+                         std::shared_ptr<DocumentStoreManager> docStoreManager);
     virtual ~MasterProcessSession();
 
     bool haveSeparateProcess();
@@ -41,6 +42,8 @@ public:
      */
     std::string getSaveAs();
 
+    std::shared_ptr<DocumentStoreManager> getDocumentStoreManager() const { return _docStoreManager; }
+
  protected:
     bool invalidateTiles(const char *buffer, int length, Poco::StringTokenizer& tokens);
 
@@ -86,6 +89,7 @@ private:
     int _loadPart;
     /// Kind::ToClient instances store URLs of completed 'save as' documents.
     MessageQueue _saveAsQueue;
+    std::shared_ptr<DocumentStoreManager> _docStoreManager;
 };
 
 #endif
diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index 7464b93..02d1815 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -67,7 +67,7 @@ public:
     HTTPWSTest()
         : _uri("http://127.0.0.1:" + std::to_string(ClientPortNumber)),
           _session(_uri.getHost(), _uri.getPort()),
-          _request(Poco::Net::HTTPRequest::HTTP_GET, "/ws")
+          _request(Poco::Net::HTTPRequest::HTTP_GET, "/")
     {
     }
 


More information about the Libreoffice-commits mailing list