wsd: allow for recovering from unloading document

When the last connection is closed, we flag the
document for unloading, until we save and
unload and have nothing further to do. However,
if during that time a new client joins the
document, we reset the unloading state and
recover.

A previously failing and disabled test is now
re-enabled and passes.

Change-Id: I425a9286ec5df56064132e5e4227227761c65830
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
pull/8816/head
Ashod Nakashian 2024-04-18 05:14:01 -04:00 committed by Ashod Nakashian
parent 9eeed4d950
commit 1e206ac001
4 changed files with 21 additions and 5 deletions

View File

@ -47,8 +47,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testExoticLang);
CPPUNIT_TEST(testSaveOnDisconnect);
// This test is failing
//CPPUNIT_TEST(testReloadWhileDisconnecting);
CPPUNIT_TEST(testReloadWhileDisconnecting);
CPPUNIT_TEST(testInactiveClient);
CPPUNIT_TEST(testViewInfoMsg);
CPPUNIT_TEST(testUndoConflict);
@ -214,11 +213,12 @@ void HTTPWSTest::testReloadWhileDisconnecting()
TST_LOG("Loading again.");
socket = loadDocAndGetSession(_socketPoll, _uri, documentURL, testname);
// Check if the document contains the pasted text.
TST_LOG("Checking if the document contains the pasted text.");
const std::string expected = "aaa bbb ccc";
const std::string selection = getAllText(socket, testname, expected);
LOK_ASSERT_EQUAL(std::string("textselectioncontent: ") + expected, selection);
TST_LOG("Closing connection after getting pasted text.");
socket->asyncShutdown();
LOK_ASSERT_MESSAGE("Expected successful disconnection of the WebSocket",

View File

@ -133,7 +133,7 @@ findOrCreateDocBroker(DocumentBroker::ChildType type, const std::string& uri,
docBroker = it->second;
// Destroying the document? Let the client reconnect.
if (docBroker->isUnloading())
if (docBroker->isUnloadingUnrecoverably())
{
LOG_WRN("DocBroker [" << docKey
<< "] is unloading. Rejecting client request to load session ["

View File

@ -3063,7 +3063,7 @@ std::shared_ptr<ClientSession> DocumentBroker::createNewClientSession(
{
try
{
if (isMarkedToDestroy() || _docState.isUnloadRequested())
if (isMarkedToDestroy() || _docState.isCloseRequested())
{
LOG_WRN("DocBroker [" << getDocKey()
<< "] is unloading. Rejecting client request to load session ["
@ -3092,6 +3092,14 @@ std::shared_ptr<ClientSession> DocumentBroker::createNewClientSession(
auto session = std::make_shared<ClientSession>(ws, id, shared_from_this(), uriPublic, isReadOnly, requestDetails);
session->construct();
if (_docState.isUnloadRequested())
{
// A new client has connected; recover.
LOG_DBG(
"Unload was requested after uploading, but new clients have joined. Recovering");
_docState.resetUnloadRequested();
}
return session;
}
catch (const std::exception& exc)

View File

@ -486,6 +486,13 @@ public:
_docState.isCloseRequested() || SigUtil::getShutdownRequestFlag();
}
/// True if any flag to unload or terminate is set.
bool isUnloadingUnrecoverably() const
{
return _docState.isMarkedToDestroy() || _stop || _docState.isCloseRequested() ||
SigUtil::getShutdownRequestFlag();
}
bool isMarkedToDestroy() const { return _docState.isMarkedToDestroy() || _stop; }
virtual bool handleInput(const std::shared_ptr<Message>& message);
@ -1468,6 +1475,7 @@ private:
/// Flag to unload the document. Irreversible.
void setUnloadRequested() { _unloadRequested = true; }
void resetUnloadRequested() { _unloadRequested = false; }
bool isUnloadRequested() const { return _unloadRequested; }
/// Flag that we are disconnected from the Kit. Irreversible.