[Libreoffice-commits] online.git: 4 commits - loolwsd/LoadTest.cpp loolwsd/LOOLSession.cpp loolwsd/TileCache.cpp loolwsd/TileCache.hpp
Tor Lillqvist
tml at collabora.com
Thu May 28 03:24:41 PDT 2015
loolwsd/LOOLSession.cpp | 18 ++++++++---
loolwsd/LoadTest.cpp | 15 ++++++++-
loolwsd/TileCache.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++
loolwsd/TileCache.hpp | 5 +++
4 files changed, 110 insertions(+), 6 deletions(-)
New commits:
commit d6bd6ca14000cb734a2bb858d3801a77b6160400
Author: Tor Lillqvist <tml at collabora.com>
Date: Thu May 28 13:23:25 2015 +0300
Handle nextmessage: here, too
Otherwise loadtest crashes on big tiles.
diff --git a/loolwsd/LoadTest.cpp b/loolwsd/LoadTest.cpp
index 6996c72..bac83bd 100644
--- a/loolwsd/LoadTest.cpp
+++ b/loolwsd/LoadTest.cpp
@@ -28,7 +28,7 @@
#include <Poco/Net/TCPServerConnectionFactory.h>
#include <Poco/Net/WebSocket.h>
#include <Poco/Process.h>
-#include <Poco/String.h>
+#include <Poco/StringTokenizer.h>
#include <Poco/Thread.h>
#include <Poco/Timespan.h>
#include <Poco/Timestamp.h>
@@ -58,6 +58,7 @@ using Poco::Net::TCPServerConnection;
using Poco::Net::WebSocket;
using Poco::Net::WebSocketException;
using Poco::Runnable;
+using Poco::StringTokenizer;
using Poco::Thread;
using Poco::Timespan;
using Poco::Timestamp;
@@ -101,6 +102,18 @@ public:
std::endl;
#endif
std::string response = getFirstLine(buffer, n);
+ StringTokenizer tokens(response, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+ int size;
+ if (tokens.count() == 2 && tokens[0] == "nextmessage:" && getTokenInteger(tokens[1], "size", size) && size > 0)
+ {
+ char largeBuffer[size];
+
+ n = _ws.receiveFrame(largeBuffer, size, flags);
+ // We don't actually need to do anything with the buffer in this program. We
+ // only parse status: messages and they are not preceded by nextmessage:
+ // messages.
+ }
if (response.find("status:") == 0)
{
parseStatus(response, _type, _numParts, _currentPart, _width, _height);
commit 13645eb76970f1628a394199c0d7dd1244520d59
Author: Tor Lillqvist <tml at collabora.com>
Date: Thu May 28 12:59:11 2015 +0300
There should be whitespace after the message keyword and colon
diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp
index 1903128..f5f7e36 100644
--- a/loolwsd/LOOLSession.cpp
+++ b/loolwsd/LOOLSession.cpp
@@ -742,7 +742,7 @@ extern "C"
srv->sendTextFrame("searchnotfound: " + std::string(pPayload));
break;
case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
- srv->sendTextFrame("documentsizechanged:" + std::string(pPayload));
+ srv->sendTextFrame("documentsizechanged: " + std::string(pPayload));
break;
case LOK_CALLBACK_SET_PART:
srv->sendTextFrame("setpart: " + std::string(pPayload));
commit cedee8f1a931436872a6aafd74a375bd9f0d0be3
Author: Tor Lillqvist <tml at collabora.com>
Date: Thu May 28 12:58:08 2015 +0300
Log the input to MasterProcessSession::handleInput() earlier
diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp
index d33ac13..1903128 100644
--- a/loolwsd/LOOLSession.cpp
+++ b/loolwsd/LOOLSession.cpp
@@ -124,7 +124,7 @@ MasterProcessSession::~MasterProcessSession()
bool MasterProcessSession::handleInput(char *buffer, int length)
{
- Application& app = Application::instance();
+ Application::instance().logger().information(Util::logPrefix() + "Input: " + getAbbreviatedMessage(buffer, length));
std::string firstLine = getFirstLine(buffer, length);
StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
@@ -175,8 +175,6 @@ bool MasterProcessSession::handleInput(char *buffer, int length)
return true;
}
- app.logger().information(Util::logPrefix() + "Input: " + getAbbreviatedMessage(buffer, length));
-
if (tokens[0] == "child")
{
if (_kind != Kind::ToPrisoner)
commit 009241447054156720d8f5df7ef37241fd0784c6
Author: Tor Lillqvist <tml at collabora.com>
Date: Thu May 28 12:53:14 2015 +0300
Handle LOK_CALLBACK_DOCUMENT_SIZE_CHANGED callbacks more cleverly
When a child process sends a documentsizechanged: message to the parent, to be
forwarded to the client, parse it and update a cached status of the doucment,
if available, and send an updated status: message to the client instead.
Note that clients should not rely on getting only status: messages and never
documentsizechanged: messages, though; the cache might be cleaned at any time
even while the server is running. If there is no cached status of the document
to update and re-use, we have to forward the documentsizechanged: message as
such to the client.
diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp
index ce273b7..d33ac13 100644
--- a/loolwsd/LOOLSession.cpp
+++ b/loolwsd/LOOLSession.cpp
@@ -134,7 +134,7 @@ bool MasterProcessSession::handleInput(char *buffer, int length)
// Note that this handles both forwarding requests from the client to the child process, and
// forwarding replies from the child process to the client. Or does it?
- // Snoop at tile: and status: messages and cache them
+ // Snoop at tile:, status: and documentsizechanged: messages and (re-)cache them
auto peer = _peer.lock();
if (_kind == Kind::ToPrisoner && peer && peer->_tileCache)
{
@@ -159,6 +159,16 @@ bool MasterProcessSession::handleInput(char *buffer, int length)
assert(firstLine.size() == static_cast<std::string::size_type>(length));
peer->_tileCache->saveStatus(firstLine);
}
+ else if (tokens[0] == "documentsizechanged:")
+ {
+ std::string statusMessage;
+ assert(firstLine.size() == static_cast<std::string::size_type>(length));
+ if (peer->_tileCache->updateSizeInStatus(firstLine, statusMessage))
+ {
+ forwardToPeer(statusMessage.c_str(), statusMessage.size());
+ return true;
+ }
+ }
}
forwardToPeer(buffer, length);
diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp
index 1828e89..5b217ab 100644
--- a/loolwsd/TileCache.cpp
+++ b/loolwsd/TileCache.cpp
@@ -9,6 +9,7 @@
#include "config.h"
+#include <cassert>
#include <fstream>
#include <iostream>
#include <memory>
@@ -17,8 +18,14 @@
#include <Poco/File.h>
#include <Poco/Path.h>
#include <Poco/SHA1Engine.h>
+#include <Poco/StringTokenizer.h>
+#include <Poco/Util/Application.h>
+#include "LOOLProtocol.hpp"
#include "TileCache.hpp"
+#include "Util.hpp"
+
+using namespace LOOLProtocol;
TileCache::TileCache(const std::string& docURL) :
_docURL(docURL)
@@ -101,6 +108,10 @@ void TileCache::saveStatus(const std::string& status)
Poco::File(dirName).createDirectories();
+ Poco::StringTokenizer tokens(status, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
+
+ assert(tokens[0] == "status:");
+
std::string fileName = dirName + "/status.txt";
std::fstream statusStream(fileName, std::ios::out);
@@ -111,6 +122,73 @@ void TileCache::saveStatus(const std::string& status)
statusStream.close();
}
+bool TileCache::updateSizeInStatus(const std::string& status, std::string& newStatus)
+{
+ std::string dirName = cacheDirName();
+
+ Poco::StringTokenizer tokens(status, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
+
+ assert(tokens[0] == "documentsizechanged:");
+
+ // These messages are constructed directly from the payload in the LO callback. If the payload
+ // does not seem to be like we expect, ignore it here. Just let it be passed on to the client.
+
+ if (tokens.count() != 3)
+ return false;
+
+ int newWidth = std::stoi(tokens[1]);
+ int newHeight = std::stoi(tokens[2]);
+
+ if (newWidth < 0 || newHeight < 0)
+ return false;
+
+ // Update the size in the cached status, if any
+ std::string fileName = dirName + "/status.txt";
+ std::fstream statusStream(fileName, std::ios::in);
+
+ if (!statusStream.is_open())
+ return false;
+
+ std::string line;
+ std::getline(statusStream, line);
+ statusStream.close();
+
+ Poco::StringTokenizer oldTokens(line, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
+
+ std::string type;
+ int parts, current, width, height;
+ if (oldTokens.count() != 6 ||
+ oldTokens[0] != "status:" ||
+ !getTokenString(oldTokens[1], "type", type) ||
+ !getTokenInteger(oldTokens[2], "parts", parts) ||
+ !getTokenInteger(oldTokens[3], "current", current) ||
+ !getTokenInteger(oldTokens[4], "width", width) ||
+ !getTokenInteger(oldTokens[5], "height", height))
+ {
+ // Existing status file has wrong syntax. It is useless anyway, delete it.
+ Poco::Util::Application::instance().logger().error(Util::logPrefix() + "Cached status '" + fileName + "' is bogus, removing");
+ std::remove(fileName.c_str());
+
+ return false;
+ }
+
+ statusStream.open(fileName, std::ios::out);
+ if (!statusStream.is_open())
+ return false;
+
+ line = ("status:"
+ " type=" + type +
+ " parts=" + std::to_string(parts) +
+ " current=" + std::to_string(current) +
+ " width=" + std::to_string(newWidth) +
+ " height=" + std::to_string(newHeight));
+ statusStream << line << std::endl;
+ statusStream.close();
+
+ newStatus = line;
+ return true;
+}
+
std::string TileCache::cacheDirName()
{
Poco::SHA1Engine digestEngine;
diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp
index e97b0e9..a6248de 100644
--- a/loolwsd/TileCache.hpp
+++ b/loolwsd/TileCache.hpp
@@ -24,8 +24,13 @@ public:
std::unique_ptr<std::fstream> lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
void saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size);
std::string getStatus();
+
+ // The parameter is a status: message
void saveStatus(const std::string& status);
+ // The parameter is a documentsizechanged: message
+ bool updateSizeInStatus(const std::string& status, std::string& newStatus);
+
private:
std::string cacheDirName();
std::string cacheFileName(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight);
More information about the Libreoffice-commits
mailing list