loolwsd: canceltiles re-designed using tilecache instead of queue
Change-Id: I4b9ba91ee08bc9dd8d27df275e303f5517d9740c Reviewed-on: https://gerrit.libreoffice.org/28526 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com>
This commit is contained in:
parent
fad6715f7d
commit
571ff06906
8 changed files with 58 additions and 10 deletions
|
@ -119,12 +119,6 @@ bool ChildSession::_handleInput(const char *buffer, int length)
|
|||
// Just to update the activity of a view-only client.
|
||||
return true;
|
||||
}
|
||||
else if (tokens[0] == "canceltiles")
|
||||
{
|
||||
// This command makes sense only on the command queue level.
|
||||
// Shouldn't get this here.
|
||||
return true;
|
||||
}
|
||||
else if (tokens[0] == "commandvalues")
|
||||
{
|
||||
return getCommandValues(buffer, length, tokens);
|
||||
|
|
|
@ -147,10 +147,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
|
|||
}
|
||||
else if (tokens[0] == "canceltiles")
|
||||
{
|
||||
if (!_peer.expired())
|
||||
{
|
||||
return forwardToPeer(_peer, buffer, length, false);
|
||||
}
|
||||
_docBroker->cancelTileRequests(shared_from_this());
|
||||
}
|
||||
else if (tokens[0] == "commandvalues")
|
||||
{
|
||||
|
|
|
@ -613,6 +613,13 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined,
|
|||
}
|
||||
}
|
||||
|
||||
void DocumentBroker::cancelTileRequests(const std::shared_ptr<ClientSession>& session)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
|
||||
tileCache().cancelTiles(session);
|
||||
}
|
||||
|
||||
void DocumentBroker::handleTileResponse(const std::vector<char>& payload)
|
||||
{
|
||||
const std::string firstLine = getFirstLine(payload);
|
||||
|
|
|
@ -214,6 +214,8 @@ public:
|
|||
void handleTileCombinedRequest(TileCombined& tileCombined,
|
||||
const std::shared_ptr<ClientSession>& session);
|
||||
|
||||
void cancelTileRequests(const std::shared_ptr<ClientSession>& session);
|
||||
|
||||
void handleTileResponse(const std::vector<char>& payload);
|
||||
void handleTileCombinedResponse(const std::vector<char>& payload);
|
||||
|
||||
|
|
|
@ -461,4 +461,26 @@ int TileCache::subscribeToTileRendering(const TileDesc& tile, const std::shared_
|
|||
}
|
||||
}
|
||||
|
||||
void TileCache::cancelTiles(const std::shared_ptr<ClientSession> &subscriber)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex);
|
||||
|
||||
const auto sub = subscriber.get();
|
||||
|
||||
Log::trace("Cancelling tiles for " + subscriber->getName());
|
||||
|
||||
for (auto it = _tilesBeingRendered.begin(); it != _tilesBeingRendered.end(); )
|
||||
{
|
||||
auto& subscribers = it->second->_subscribers;
|
||||
Log::trace("Tile " + it->first + " has " + std::to_string(subscribers.size()) + " subscribers.");
|
||||
subscribers.erase(std::remove_if(subscribers.begin(), subscribers.end(),
|
||||
[sub](std::weak_ptr<ClientSession>& ptr){ return ptr.lock().get() == sub; }),
|
||||
subscribers.end());
|
||||
Log::trace(" Tile " + it->first + " has " + std::to_string(subscribers.size()) + " subscribers.");
|
||||
|
||||
// Remove if there are no more subscribers on this tile.
|
||||
it = (subscribers.empty() ? _tilesBeingRendered.erase(it) : ++it);
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -42,6 +42,9 @@ public:
|
|||
/// Otherwise returns 0 to signify a subscription exists.
|
||||
int subscribeToTileRendering(const TileDesc& tile, const std::shared_ptr<ClientSession> &subscriber);
|
||||
|
||||
/// Cancels all tile requests by the given subscriber.
|
||||
void cancelTiles(const std::shared_ptr<ClientSession> &subscriber);
|
||||
|
||||
std::unique_ptr<std::fstream> lookupTile(const TileDesc& tile);
|
||||
|
||||
void saveTileAndNotify(const TileDesc& tile, const char *data, const size_t size, const bool priority);
|
||||
|
|
|
@ -33,6 +33,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture
|
|||
CPPUNIT_TEST(testSimple);
|
||||
CPPUNIT_TEST(testSimpleCombine);
|
||||
CPPUNIT_TEST(testPerformance);
|
||||
CPPUNIT_TEST(testCancelTiles);
|
||||
CPPUNIT_TEST(testUnresponsiveClient);
|
||||
CPPUNIT_TEST(testClientPartImpress);
|
||||
CPPUNIT_TEST(testClientPartCalc);
|
||||
|
@ -48,6 +49,7 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture
|
|||
void testSimple();
|
||||
void testSimpleCombine();
|
||||
void testPerformance();
|
||||
void testCancelTiles();
|
||||
void testUnresponsiveClient();
|
||||
void testClientPartImpress();
|
||||
void testClientPartCalc();
|
||||
|
@ -208,6 +210,18 @@ void TileCacheTests::testPerformance()
|
|||
socket.shutdown();
|
||||
}
|
||||
|
||||
void TileCacheTests::testCancelTiles()
|
||||
{
|
||||
const auto testName = "cancelTiles ";
|
||||
auto socket = *loadDocAndGetSocket("load12.ods", _uri, testName);
|
||||
|
||||
// Request a huge tile, and cancel immediately.
|
||||
sendTextFrame(socket, "tilecombine part=0 width=2560 height=2560 tileposx=0 tileposy=0 tilewidth=38400 tileheight=38400");
|
||||
sendTextFrame(socket, "canceltiles");
|
||||
|
||||
assertNotInResponse(socket, "tile:", testName);
|
||||
}
|
||||
|
||||
void TileCacheTests::testUnresponsiveClient()
|
||||
{
|
||||
const std::string docFilename = "hello.odt";
|
||||
|
|
|
@ -330,6 +330,15 @@ std::string assertResponseLine(T& ws, const std::string& prefix, const std::stri
|
|||
return res;
|
||||
}
|
||||
|
||||
/// Assert that we don't get a response with the given prefix.
|
||||
template <typename T>
|
||||
std::string assertNotInResponse(T& ws, const std::string& prefix, const std::string name = "")
|
||||
{
|
||||
const auto res = getResponseLine(ws, prefix, name);
|
||||
CPPUNIT_ASSERT_MESSAGE("Did not expect getting message [" + res + "].", res.empty());
|
||||
return res;
|
||||
}
|
||||
|
||||
inline
|
||||
void getResponseMessage(const std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& prefix, std::string& response, const bool isLine)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue