[Libreoffice-commits] online.git: Branch 'feature/latency' - 3 commits - common/Rectangle.hpp loleaflet/src wsd/ClientSession.cpp wsd/ClientSession.hpp

Tamás Zolnai tamas.zolnai at collabora.com
Sat Jun 9 20:01:15 UTC 2018


 common/Rectangle.hpp                  |    5 +++
 loleaflet/src/layer/tile/GridLayer.js |   13 ++++++++++
 loleaflet/src/layer/tile/TileLayer.js |   28 +++++++--------------
 wsd/ClientSession.cpp                 |   44 ++++++++++++++++++++++++++++++++++
 wsd/ClientSession.hpp                 |    5 +++
 5 files changed, 76 insertions(+), 19 deletions(-)

New commits:
commit 415d35a71c8133b489042ce1a14f35987c5747fd
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Sat Jun 9 21:33:44 2018 +0200

    Send the right visible area to the server
    
    Change-Id: I036dfaa566fa7d4e370386d839bd2397cbf929f8

diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js
index 8a37a04dd..c61c6bb05 100644
--- a/loleaflet/src/layer/tile/GridLayer.js
+++ b/loleaflet/src/layer/tile/GridLayer.js
@@ -572,6 +572,7 @@ L.GridLayer = L.Layer.extend({
 			this._addTiles(queue, fragment);
 			this._level.el.appendChild(fragment);
 		}
+		this._invalidateClientVisibleArea();
 	},
 
 	_updateOnChangePart: function () {
@@ -719,6 +720,18 @@ L.GridLayer = L.Layer.extend({
 		}
 	},
 
+
+	_invalidateClientVisibleArea: function() {
+		if (this._debug) {
+			this._debugInfo.clearLayers();
+			for (var key in this._tiles) {
+				this._tiles[key]._debugPopup = null;
+				this._tiles[key]._debugTile = null;
+			}
+		}
+		this._clientVisibleArea = true;
+	},
+
 	_isValidTile: function (coords) {
 		if (coords.x < 0 || coords.y < 0) {
 			return false;
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 0ad81644c..6aec6514b 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -1479,10 +1479,11 @@ L.TileLayer = L.GridLayer.extend({
 
 		if (this._clientVisibleArea) {
 			// Visible area is dirty, update it on the server.
-			var visibleArea = this._map._container.getBoundingClientRect();
-			var pos = this._pixelsToTwips(new L.Point(visibleArea.left, visibleArea.top));
-			var size = this._pixelsToTwips(new L.Point(visibleArea.width, visibleArea.height));
-			var payload = 'clientvisiblearea x=' + Math.round(pos.x) + ' y=' + Math.round(pos.y) +
+			var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+			var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+			var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+			var size = new L.Point(visibleArea.getSize().x, visibleArea.getSize().y);
+			var payload = 'clientvisiblearea x=' + Math.round(visibleTopLeft.x) + ' y=' + Math.round(visibleTopLeft.y) +
 				' width=' + Math.round(size.x) + ' height=' + Math.round(size.y);
 			this._map._socket.sendMessage(payload);
 			this._clientVisibleArea = false;
@@ -1520,10 +1521,11 @@ L.TileLayer = L.GridLayer.extend({
 		}
 		if (this._clientVisibleArea) {
 			// Visible area is dirty, update it on the server.
-			var visibleArea = this._map._container.getBoundingClientRect();
-			var pos = this._pixelsToTwips(new L.Point(visibleArea.left, visibleArea.top));
-			var size = this._pixelsToTwips(new L.Point(visibleArea.width, visibleArea.height));
-			var payload = 'clientvisiblearea x=' + Math.round(pos.x) + ' y=' + Math.round(pos.y) +
+			var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+			var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+			var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+			var size = new L.Point(visibleArea.getSize().x, visibleArea.getSize().y);
+			var payload = 'clientvisiblearea x=' + Math.round(visibleTopLeft.x) + ' y=' + Math.round(visibleTopLeft.y) +
 				' width=' + Math.round(size.x) + ' height=' + Math.round(size.y);
 			this._map._socket.sendMessage(payload);
 			this._clientVisibleArea = false;
@@ -2281,16 +2283,6 @@ L.TileLayer = L.GridLayer.extend({
 			'tiletwipheight=' + this._tileHeightTwips;
 	},
 
-	_invalidateClientVisibleArea: function() {
-		if (this._debug) {
-			this._debugInfo.clearLayers();
-			for (var key in this._tiles) {
-				this._tiles[key]._debugPopup = null;
-				this._tiles[key]._debugTile = null;
-			}
-		}
-		this._clientVisibleArea = true;
-	},
 
 	_debugGetTimeArray: function() {
 		return {count: 0, ms: 0, best: Number.MAX_SAFE_INTEGER, worst: 0, date: 0};
commit 1f728a9681e8ecf08556f677d9a6808bfaa3c15a
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Fri Jun 8 14:51:37 2018 +0200

    Add a timeout for tileprocesses message handling
    
    For debug purposes.
    
    Change-Id: Icc9dfc05b18f9da96b29b7cadeb57f7218832295

diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index be906005f..ba2330540 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -75,6 +75,8 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     const std::string firstLine = getFirstLine(buffer, length);
     const std::vector<std::string> tokens = LOOLProtocol::tokenize(firstLine.data(), firstLine.size());
 
+    checkTileRequestTimout();
+
     std::shared_ptr<DocumentBroker> docBroker = getDocumentBroker();
     if (!docBroker)
     {
@@ -326,7 +328,13 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     else if (tokens[0] == "tileprocessed")
     {
         if(_tilesOnFly > 0) // canceltiles message can zero this value
+        {
             --_tilesOnFly;
+            if(_tilesOnFly == 0)
+            {
+                _tileCounterStartTime = boost::none;
+            }
+        }
         docBroker->sendRequestedTiles(shared_from_this());
         return true;
     }
@@ -962,6 +970,19 @@ Authorization ClientSession::getAuthorization() const
     return Authorization();
 }
 
+void ClientSession::setTilesOnFly(int tilesOnFly)
+{
+    _tilesOnFly = tilesOnFly;
+    if(tilesOnFly == 0)
+    {
+        _tileCounterStartTime = boost::none;
+    }
+    else
+    {
+        _tileCounterStartTime = std::chrono::steady_clock::now();
+    }
+}
+
 void ClientSession::onDisconnect()
 {
     LOG_INF(getName() << " Disconnected, current number of connections: " << LOOLWSD::NumConnections);
@@ -1095,4 +1116,18 @@ void ClientSession::handleTileInvalidation(const std::string& message,
     }
 }
 
+void ClientSession::checkTileRequestTimout()
+{
+    if(_tileCounterStartTime != boost::none)
+    {
+        const auto duration = std::chrono::steady_clock::now() - _tileCounterStartTime.get();
+        if( std::chrono::duration_cast<std::chrono::seconds>(duration).count() > 2)
+        {
+            LOG_WRN("Tile request timeout: server waits too long for tileprocessed messages.");
+            std::cerr << "Tile request timeout: server waits too long for tileprocessed messages." << std::endl;
+            _tileCounterStartTime = boost::none;
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 824ee80b2..abd535891 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -110,7 +110,7 @@ public:
     boost::optional<TileCombined>& getRequestedTiles() { return _requestedTiles; }
 
     int getTilesOnFly() const { return _tilesOnFly; }
-    void setTilesOnFly(int tilesOnFly) { _tilesOnFly = tilesOnFly; }
+    void setTilesOnFly(int tilesOnFly);
 
 
 private:
@@ -153,6 +153,8 @@ private:
     void handleTileInvalidation(const std::string& message,
                                 const std::shared_ptr<DocumentBroker>& docBroker);
 
+    void checkTileRequestTimout();
+
 private:
     std::weak_ptr<DocumentBroker> _docBroker;
 
@@ -195,6 +197,7 @@ private:
     std::string _docType;
 
     int _tilesOnFly;
+    boost::optional<std::chrono::time_point<std::chrono::steady_clock>> _tileCounterStartTime;
 
     boost::optional<TileCombined> _requestedTiles;
 };
commit 8194ed5cd697a305ffc8bb7d845d27514de52ee5
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Fri Jun 8 14:01:11 2018 +0200

    Don't request new tiles by invalidation without valid client data
    
    Change-Id: I9972ced6c15b9d5aa8918811aa057cdc73a5b086

diff --git a/common/Rectangle.hpp b/common/Rectangle.hpp
index c6c6efce4..1300aa71a 100644
--- a/common/Rectangle.hpp
+++ b/common/Rectangle.hpp
@@ -73,6 +73,11 @@ struct Rectangle
     {
         return _x1 <= _x2 && _y1 <= _y2;
     }
+
+    bool hasSurface()
+    {
+        return _x1 < _x2 && _y1 < _y2;
+    }
 };
 
 }
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index b5bd45c2b..be906005f 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -1044,6 +1044,15 @@ void ClientSession::dumpState(std::ostream& os)
 void ClientSession::handleTileInvalidation(const std::string& message,
     const std::shared_ptr<DocumentBroker>& docBroker)
 {
+    // Skip requesting new tiles if we don't have client visible area data yet.
+    if(!_clientVisibleArea.hasSurface() ||
+       _tileWidthPixel == 0 || _tileHeightPixel == 0 ||
+       _tileWidthTwips == 0 || _tileHeightTwips == 0)
+    {
+        return;
+    }
+
+
     docBroker->invalidateTiles(message);
     std::pair<int, Util::Rectangle> result = TileCache::parseInvalidateMsg(message);
     int part = result.first;


More information about the Libreoffice-commits mailing list