[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