bgsave: add a 'finalWrite' parameter, to keep various saves sync.

Avoid complexity and wasteful creation of new processes in many cases.

Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
Change-Id: If7713f80b390a8e0e53b7253244b838b325b745c
pull/9098/head
Michael Meeks 2024-05-18 11:47:00 +01:00
parent 1eacc719e4
commit dcfc3f3c0f
2 changed files with 28 additions and 16 deletions

View File

@ -1435,7 +1435,8 @@ void DocumentBroker::startRenameFileCommand()
constexpr bool dontTerminateEdit = false; // We will save, rename, and reload: terminate.
constexpr bool dontSaveIfUnmodified = true;
constexpr bool isAutosave = false;
sendUnoSave(it->second, dontTerminateEdit, dontSaveIfUnmodified, isAutosave);
constexpr bool finalWrite = true;
sendUnoSave(it->second, dontTerminateEdit, dontSaveIfUnmodified, isAutosave, finalWrite);
}
void DocumentBroker::endRenameFileCommand()
@ -2438,14 +2439,15 @@ bool DocumentBroker::manualSave(const std::shared_ptr<ClientSession>& session,
{
LOG_DBG("Manual save by " << session->getName() << " on docKey [" << _docKey << ']');
return sendUnoSave(session, dontTerminateEdit, dontSaveIfUnmodified,
/*isAutosave=*/false, extendedData);
/*isAutosave=*/false, /*finalWrite=*/false, extendedData);
}
LOG_DBG("Document [" << _docKey << "] is currently saving and cannot issue another save");
return false;
}
bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified)
bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified,
const bool finalWrite)
{
ASSERT_CORRECT_THREAD();
@ -2459,8 +2461,9 @@ bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified)
_saveManager.autoSaveChecked();
LOG_TRC("autoSave(): forceful? " << force
<< ", dontSaveIfUnmodified: " << dontSaveIfUnmodified);
LOG_TRC("autoSave(): forceful? " << force <<
", dontSaveIfUnmodified: " << dontSaveIfUnmodified <<
" finalWrite : " << finalWrite);
const CanSave canSave = canSaveToDisk();
if (canSave != CanSave::Yes)
@ -2507,7 +2510,7 @@ bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified)
// triggered when the document is closed. In the case of network disconnection or browser crash
// most users would want to have had the chance to hit save before the document unloaded.
sent = sendUnoSave(savingSession, /*dontTerminateEdit=*/true, dontSaveIfUnmodified,
/*isAutosave=*/false);
/*isAutosave=*/false, finalWrite);
}
else if (isModified())
{
@ -2540,7 +2543,8 @@ bool DocumentBroker::autoSave(const bool force, const bool dontSaveIfUnmodified)
{
LOG_TRC("Sending timed save command for [" << _docKey << ']');
sent = sendUnoSave(savingSession, /*dontTerminateEdit=*/true,
/*dontSaveIfUnmodified=*/true, /*isAutosave=*/true);
/*dontSaveIfUnmodified=*/true, /*isAutosave=*/true,
finalWrite);
}
}
@ -2651,7 +2655,7 @@ void DocumentBroker::autoSaveAndStop(const std::string& reason)
<< "] before terminating. isPossiblyModified: "
<< (possiblyModified ? "yes" : "no")
<< ", conflict: " << (_documentChangedInStorage ? "yes" : "no"));
if (!autoSave(/*force=*/possiblyModified, /*dontSaveIfUnmodified=*/true))
if (!autoSave(/*force=*/possiblyModified, /*dontSaveIfUnmodified=*/true, /*finalWrite=*/true))
{
// Nothing to save. Try to upload if necessary.
const auto session = getWriteableSession();
@ -2701,7 +2705,8 @@ void DocumentBroker::autoSaveAndStop(const std::string& reason)
bool DocumentBroker::sendUnoSave(const std::shared_ptr<ClientSession>& session,
bool dontTerminateEdit, bool dontSaveIfUnmodified,
bool isAutosave, const std::string& extendedData)
bool isAutosave, bool finalWrite,
const std::string& extendedData)
{
ASSERT_CORRECT_THREAD();
@ -2740,12 +2745,15 @@ bool DocumentBroker::sendUnoSave(const std::shared_ptr<ClientSession>& session,
// If Core does report something different after saving, we'll update this flag.
_nextStorageAttrs.setUserModified(isModified() || haveModifyActivityAfterSaveRequest());
static bool forceBackgroundSave = !!getenv("COOL_FORCE_BGSAVE");
static bool forceBackgroundEnv = !!getenv("COOL_FORCE_BGSAVE");
// Note: It's odd to capture these here, but this function is used from ClientSession too.
bool autosave = isAutosave || (_unitWsd && _unitWsd->isAutosave());
bool background =
forceBackgroundSave || (autosave && _backgroundAutoSave) || _backgroundManualSave;
bool backgroundConfigured = (autosave && _backgroundAutoSave) || _backgroundManualSave;
bool background = forceBackgroundEnv || (!finalWrite && backgroundConfigured);
if (finalWrite)
LOG_TRC("suspected final save: don't do background write");
_nextStorageAttrs.setIsAutosave(autosave);
_nextStorageAttrs.setExtendedData(extendedData);
@ -2939,7 +2947,8 @@ std::size_t DocumentBroker::removeSession(const std::shared_ptr<ClientSession>&
// If always_save_on_exit=true, issue a save to guarantee uploading if necessary.
if (!lastEditableSession ||
(!_saveManager.isSaving() &&
!autoSave(/*force=*/_alwaysSaveOnExit || isPossiblyModified(), dontSaveIfUnmodified)))
!autoSave(/*force=*/_alwaysSaveOnExit || isPossiblyModified(),
dontSaveIfUnmodified, /*finalWrite=*/true)))
{
disconnectSessionInternal(session);
}
@ -4355,6 +4364,7 @@ void DocumentBroker::dumpState(std::ostream& os)
os << "\n wopiDownloadDuration (ms): " << _wopiDownloadDuration.count();
os << "\n alwaysSaveOnExit: " << (_alwaysSaveOnExit?"true":"false");
os << "\n backgroundAutoSave: " << (_backgroundAutoSave?"true":"false");
os << "\n backgroundManualSave: " << (_backgroundManualSave?"true":"false");
os << "\n isViewFileExtension: " << _isViewFileExtension;
#if !MOBILEAPP
os << "\n last quarantined version: "
@ -4501,7 +4511,8 @@ void DocumentBroker::startSwitchingToOffline(const std::shared_ptr<ClientSession
constexpr bool dontTerminateEdit = false; // We will save and reload: terminate.
constexpr bool dontSaveIfUnmodified = true;
constexpr bool isAutosave = false;
sendUnoSave(session, dontTerminateEdit, dontSaveIfUnmodified, isAutosave);
constexpr bool finalWrite = true;
sendUnoSave(session, dontTerminateEdit, dontSaveIfUnmodified, isAutosave, finalWrite);
}
void DocumentBroker::endSwitchingToOffline()

View File

@ -402,9 +402,10 @@ public:
/// @param force when true, will force saving if there
/// has been any recent activity after the last save.
/// @param dontSaveIfUnmodified when true, save will fail if the document is not modified.
/// @param finalWrite this is our last write before exit, lets make it synchronous
/// @return true if attempts to save or it also waits
/// and receives save notification. Otherwise, false.
bool autoSave(const bool force, const bool dontSaveIfUnmodified);
bool autoSave(const bool force, const bool dontSaveIfUnmodified, const bool finalWrite = false);
/// Saves the document and stops if there was nothing to autosave.
void autoSaveAndStop(const std::string& reason);
@ -746,7 +747,7 @@ private:
/// Sends the .uno:Save command to LoKit.
bool sendUnoSave(const std::shared_ptr<ClientSession>& session, bool dontTerminateEdit = true,
bool dontSaveIfUnmodified = true, bool isAutosave = false,
bool dontSaveIfUnmodified = true, bool isAutosave = false, bool finalWrite = false,
const std::string& extendedData = std::string());
/**