[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