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.nakash...@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 <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@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, "/") { } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits