[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-3' - common/Common.hpp test/TileCacheTests.cpp wsd/ClientSession.cpp wsd/ClientSession.hpp wsd/DocumentBroker.cpp
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Mon Oct 1 11:17:12 UTC 2018
common/Common.hpp | 2 +
test/TileCacheTests.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
wsd/ClientSession.cpp | 18 +++++++++++--
wsd/ClientSession.hpp | 3 +-
wsd/DocumentBroker.cpp | 16 +++++++++++-
5 files changed, 96 insertions(+), 5 deletions(-)
New commits:
commit ea871566685f64949080735d430c7f767c63f582
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Sep 28 19:30:57 2018 +0200
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Mon Oct 1 13:16:54 2018 +0200
Upper limit of sent out versions of the same tile
We try to decrease the network usage with avoiding sending out
to much tiles to the client. When we already sent out two versions
of the same tile without having the tileprocessed message from the
client we delay sending out the next version to avoid spamming tiles
on the network.
Change-Id: Ia47cd7c0d3fb829f6777f0c3265970433591df19
(cherry picked from commit ac2cd92d25815cd476008c6cd8035e989d0c8826)
Reviewed-on: https://gerrit.libreoffice.org/61129
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
Tested-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/common/Common.hpp b/common/Common.hpp
index 978ef2c18..29008fd24 100644
--- a/common/Common.hpp
+++ b/common/Common.hpp
@@ -20,6 +20,8 @@ constexpr int CHILD_REBALANCE_INTERVAL_MS = CHILD_TIMEOUT_MS / 10;
constexpr int POLL_TIMEOUT_MS = COMMAND_TIMEOUT_MS / 10;
constexpr int WS_SEND_TIMEOUT_MS = 1000;
+constexpr int TILE_ROUNDTRIP_TIMEOUT_MS = 5000;
+
/// Pipe and Socket read buffer size.
/// Should be large enough for ethernet packets
/// which can be 1500 bytes long.
diff --git a/test/TileCacheTests.cpp b/test/TileCacheTests.cpp
index 535bafc30..f8eefa278 100644
--- a/test/TileCacheTests.cpp
+++ b/test/TileCacheTests.cpp
@@ -81,6 +81,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture
//CPPUNIT_TEST(testTileInvalidatePartImpress);
CPPUNIT_TEST(testTileBeingRenderedHandling);
CPPUNIT_TEST(testWireIDFilteringOnWSDSide);
+ CPPUNIT_TEST(testLimitTileVersionsOnFly);
CPPUNIT_TEST_SUITE_END();
@@ -106,6 +107,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture
void testTileInvalidatePartImpress();
void testTileBeingRenderedHandling();
void testWireIDFilteringOnWSDSide();
+ void testLimitTileVersionsOnFly();
void checkTiles(std::shared_ptr<LOOLWebSocket>& socket,
const std::string& type,
@@ -1282,6 +1284,66 @@ void TileCacheTests::testWireIDFilteringOnWSDSide()
CPPUNIT_ASSERT_MESSAGE("Not expected tile message arrived!", tile.empty());
}
+void TileCacheTests::testLimitTileVersionsOnFly()
+{
+ // We have an upper limit (2) for the versions of the same tile wsd send out
+ // without getting the tileprocessed message for the first tile message.
+ const char* testname = "testLimitTileVersionsOnFly ";
+
+ std::string documentPath, documentURL;
+ getDocumentPathAndURL("empty.odt", documentPath, documentURL, testname);
+ std::shared_ptr<LOOLWebSocket> socket = loadDocAndGetSocket(_uri, documentURL, testname);
+
+ // Set the client visible area
+ sendTextFrame(socket, "clientvisiblearea x=-2662 y=0 width=16000 height=9875");
+ sendTextFrame(socket, "clientzoom tilepixelwidth=256 tilepixelheight=256 tiletwipwidth=3200 tiletwipheight=3200");
+
+ // Type one character to trigger sending tiles
+ sendChar(socket, 'x', skNone, testname);
+
+ // Handle all tiles send by wsd
+ bool getTileResp = false;
+ do
+ {
+ std::string tile = getResponseString(socket, "tile:", testname, 1000);
+ getTileResp = !tile.empty();
+ } while(getTileResp);
+
+ // Type an other character to trigger sending tiles
+ sendChar(socket, 'x', skNone, testname);
+
+ // Handle all tiles sent by wsd
+ getTileResp = false;
+ do
+ {
+ std::string tile = getResponseString(socket, "tile:", testname, 1000);
+ getTileResp = !tile.empty();
+ } while(getTileResp);
+
+ // For the third invalidation wsd does not send the new tile since
+ // two versions of the same tile were already sent.
+ sendChar(socket, 'x', skNone, testname);
+
+ std::vector<char> tile1 = getResponseMessage(socket, "tile:", testname, 1000);
+ CPPUNIT_ASSERT_MESSAGE("Not expected tile message arrived!", tile1.empty());
+
+ // When the next tileprocessed message arrive with correct tileID
+ // wsd sends the delayed tile
+ sendTextFrame(socket, "tileprocessed tile=0:0:0:3200:3200");
+
+ int arrivedTiles = 0;
+ bool gotTile = false;
+ do
+ {
+ std::vector<char> tile = getResponseMessage(socket, "tile:", testname, 1000);
+ gotTile = !tile.empty();
+ if(gotTile)
+ ++arrivedTiles;
+ } while(gotTile);
+
+ CPPUNIT_ASSERT_EQUAL(1, arrivedTiles);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(TileCacheTests);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 8a4bb18cd..d28915ec8 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -1100,7 +1100,7 @@ void ClientSession::removeOutdatedTilesOnFly()
{
auto tileIter = _tilesOnFly.begin();
double elapsedTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - tileIter->second).count();
- if(elapsedTimeMs > 5000.0)
+ if(elapsedTimeMs > TILE_ROUNDTRIP_TIMEOUT_MS)
{
LOG_WRN("Tracker tileID was dropped because of time out. Tileprocessed message did not arrive");
_tilesOnFly.erase(tileIter);
@@ -1110,6 +1110,18 @@ void ClientSession::removeOutdatedTilesOnFly()
}
}
+size_t ClientSession::countIdenticalTilesOnFly(const TileDesc& tile) const
+{
+ size_t count = 0;
+ std::string tileID = generateTileID(tile);
+ for(auto& tileItem : _tilesOnFly)
+ {
+ if(tileItem.first == tileID)
+ ++count;
+ }
+ return count;
+}
+
Util::Rectangle ClientSession::getNormalizedVisibleArea() const
{
Util::Rectangle normalizedVisArea;
@@ -1242,7 +1254,7 @@ void ClientSession::handleTileInvalidation(const std::string& message,
Util::Rectangle tileRect (j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips);
if(invalidateRect.intersects(tileRect))
{
- invalidTiles.emplace_back(TileDesc(part, _tileWidthPixel, _tileHeightPixel, j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips, -1, 0, -1, false));
+ invalidTiles.emplace_back(part, _tileWidthPixel, _tileHeightPixel, j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips, -1, 0, -1, false);
TileWireId oldWireId = 0;
auto iter = _oldWireIds.find(generateTileID(invalidTiles.back()));
@@ -1329,7 +1341,7 @@ void ClientSession::clearTileSubscription()
_tilesBeingRendered.clear();
}
-std::string ClientSession::generateTileID(const TileDesc& tile)
+std::string ClientSession::generateTileID(const TileDesc& tile) const
{
std::ostringstream tileID;
tileID << tile.getPart() << ":" << tile.getTilePosX() << ":" << tile.getTilePosY() << ":"
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 38da74801..eb0440046 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -110,6 +110,7 @@ public:
void clearTilesOnFly();
size_t getTilesOnFlyCount() const { return _tilesOnFly.size(); }
void removeOutdatedTilesOnFly();
+ size_t countIdenticalTilesOnFly(const TileDesc& tile) const;
Util::Rectangle getVisibleArea() const { return _clientVisibleArea; }
/// Visible area can have negative value as position, but we have tiles only in the positive range
@@ -174,7 +175,7 @@ private:
const std::shared_ptr<DocumentBroker>& docBroker);
/// Generate a unique id for a tile
- std::string generateTileID(const TileDesc& tile);
+ std::string generateTileID(const TileDesc& tile) const;
private:
std::weak_ptr<DocumentBroker> _docBroker;
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index c6b589899..02b112a95 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -1424,12 +1424,26 @@ void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& se
std::deque<TileDesc>& requestedTiles = session->getRequestedTiles();
if (!requestedTiles.empty())
{
+ size_t delayedTiles = 0;
std::vector<TileDesc> tilesNeedsRendering;
while(session->getTilesOnFlyCount() + session->getTilesBeingRenderedCount() < tilesOnFlyUpperLimit &&
- !requestedTiles.empty())
+ !requestedTiles.empty() &&
+ // If we delayed all tiles we don't send any tile (we will when next tileprocessed message arrives)
+ delayedTiles < requestedTiles.size())
{
TileDesc& tile = *(requestedTiles.begin());
+ // We already sent out two versions of the same tile, let's not send the third one
+ // until we get a tileprocessed message for this specific tile.
+ if (session->countIdenticalTilesOnFly(tile) >= 2)
+ {
+ requestedTiles.push_back(requestedTiles.front());
+ requestedTiles.pop_front();
+ delayedTiles += 1;
+ LOG_INF("Requested tile was delayed!");
+ continue;
+ }
+
// Satisfy as many tiles from the cache.
std::unique_ptr<std::fstream> cachedTile = _tileCache->lookupTile(tile);
if (cachedTile)
More information about the Libreoffice-commits
mailing list