[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt wsd/Storage.cpp wsd/Storage.hpp
Pranav Kant
pranavk at collabora.co.uk
Thu Jun 22 11:04:07 UTC 2017
loleaflet/src/core/Socket.js | 30 ++++++++++++++++++++++++++++++
wsd/ClientSession.cpp | 7 +++++++
wsd/DocumentBroker.cpp | 8 +++++---
wsd/DocumentBroker.hpp | 6 ++++++
wsd/Storage.cpp | 10 +++++++---
wsd/Storage.hpp | 8 +++++++-
wsd/protocol.txt | 4 ++++
7 files changed, 66 insertions(+), 7 deletions(-)
New commits:
commit 8f02d4b49d699d37ff979b2cb553564d8f11358b
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Jun 1 18:26:54 2017 +0530
If user commands, refresh the document for all in case of doc conflict
Change-Id: I42c61fb8099b0bcc60f942e602561cc97486a918
(cherry picked from commit 4d61cae4c8b6ecc7890fb0426c9600e1cf77bbdb)
Reviewed-on: https://gerrit.libreoffice.org/38529
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
Tested-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index 894725aa..17d73b04 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -269,6 +269,21 @@ L.Socket = L.Class.extend({
}
}, timeoutMs);
}
+ else if (textMsg.startsWith('documentconflict')) {
+ var username = textMsg.substring('documentconflict '.length);
+ msg = _('%user asked to refresh the document. Document will now refresh automatically.').replace('%user', username);
+
+ // Reload the document
+ this._map._active = false;
+ map = this._map;
+ vex.timer = setInterval(function() {
+ try {
+ // Activate and cancel timer and dialogs.
+ map._activate();
+ } catch (error) {
+ }
+ }, 3000);
+ }
// Close any open dialogs first.
if (vex.dialogID > 0) {
@@ -346,6 +361,21 @@ L.Socket = L.Class.extend({
else if (command.errorKind === 'documentconflict')
{
storageError = errorMessages.storage.documentconflict;
+ vex.dialog.confirm({
+ message: _('Document has been changed in storage. Do you want to refresh the page to load the new document ? Cancelling will continue editing and overwrite.'),
+ callback: L.bind(function(value) {
+ if (value) {
+ // They want to refresh the page and load document again for all
+ this.sendMessage('closedocument');
+ } else {
+ // They want to overwrite
+ this.sendMessage('documentconflict.overwrite');
+ }
+ }, this)
+ });
+ vex.dialogID = vex.globalID - 1;
+
+ return;
}
// Parse the storage url as link
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 7c22b04d..84558297 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -171,6 +171,13 @@ bool ClientSession::_handleInput(const char *buffer, int length)
LOG_DBG("Session [" << getId() << "] requested owner termination");
docBroker->closeDocument("ownertermination");
}
+ else if (docBroker->isDocumentChangedInStorage())
+ {
+ LOG_DBG("Document marked as changed in storage and user ["
+ << getUserId() << ", " << getUserName()
+ << "] wants to refresh the document for all.");
+ docBroker->closeDocument("documentconflict " + getUserName());
+ }
return true;
}
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 2157e191..2dc938ac 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -145,6 +145,7 @@ DocumentBroker::DocumentBroker(const std::string& uri,
_docId(Util::encodeId(DocBrokerId++, 3)),
_childRoot(childRoot),
_cacheRoot(getCachePath(uriPublic.toString())),
+ _documentChangedInStorage(false),
_lastSaveTime(std::chrono::steady_clock::now()),
_lastSaveRequestTime(std::chrono::steady_clock::now() - std::chrono::milliseconds(COMMAND_TIMEOUT_MS)),
_markToDestroy(false),
@@ -493,6 +494,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
_documentLastModifiedTime != fileInfo._modifiedTime)
{
LOG_WRN("Document [" << _docKey << "] has been modified behind our back. Informing all clients.");
+ _documentChangedInStorage = true;
// Inform all clients
for (const auto& sessionIt : _sessions)
{
@@ -651,7 +653,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId,
else if (storageSaveResult == StorageBase::SaveResult::DOC_CHANGED)
{
LOG_ERR("PutFile says that Document changed in storage");
-
+ _documentChangedInStorage = true;
// Inform all clients
for (const auto& sessionIt : _sessions)
{
@@ -1332,7 +1334,7 @@ bool DocumentBroker::forwardToClient(const std::shared_ptr<Message>& payload)
void DocumentBroker::shutdownClients(const std::string& closeReason)
{
assertCorrectThread();
- LOG_INF("Terminating " << _sessions.size() << " clients of doc [" << _docKey << "].");
+ LOG_INF("Terminating " << _sessions.size() << " clients of doc [" << _docKey << "] with reason: " << closeReason);
// First copy into local container, since removeSession
// will erase from _sessions, but will leave the last.
@@ -1374,7 +1376,7 @@ void DocumentBroker::terminateChild(const std::string& closeReason, const bool r
{
assertCorrectThread();
- LOG_INF("Terminating doc [" << _docKey << "].");
+ LOG_INF("Terminating doc [" << _docKey << "] with reason: " << closeReason);
// Close all running sessions
if (!rude)
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 23b699e4..5b9b1730 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -237,6 +237,8 @@ public:
bool isLoaded() const { return _isLoaded; }
void setLoaded();
+ bool isDocumentChangedInStorage() { return _documentChangedInStorage; }
+
/// Save the document to Storage if it needs persisting.
bool saveToStorage(const std::string& sesionId, bool success, const std::string& result = "");
bool isModified() const { return _isModified; }
@@ -377,6 +379,10 @@ private:
std::string _jailId;
std::string _filename;
+ /// Set to true when document changed in storage and we are waiting
+ /// for user's command to act.
+ bool _documentChangedInStorage;
+
/// The last time we tried saving, regardless of whether the
/// document was modified and saved or not.
std::chrono::steady_clock::time_point _lastSaveTime;
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index aee09ae9..f98769c8 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -668,9 +668,13 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const std::string& a
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
request.set("X-WOPI-Override", "PUT");
- request.set("X-LOOL-WOPI-Timestamp",
- Poco::DateTimeFormatter::format(Poco::DateTime(_fileInfo._modifiedTime),
- Poco::DateTimeFormat::ISO8601_FRAC_FORMAT));
+ if (!_forceOverwrite)
+ {
+ // Request WOPI host to not overwrite if timestamps mismatch
+ request.set("X-LOOL-WOPI-Timestamp",
+ Poco::DateTimeFormatter::format(Poco::DateTime(_fileInfo._modifiedTime),
+ Poco::DateTimeFormat::ISO8601_FRAC_FORMAT));
+ }
request.setContentType("application/octet-stream");
request.setContentLength(size);
addStorageDebugCookie(request);
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index dc29685b..5310ea8e 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -77,7 +77,8 @@ public:
_localStorePath(localStorePath),
_jailPath(jailPath),
_fileInfo("", "lool", Poco::Timestamp::fromEpochTime(0), 0),
- _isLoaded(false)
+ _isLoaded(false),
+ _forceOverwrite(false)
{
LOG_DBG("Storage ctor: " << uri.toString());
}
@@ -89,6 +90,10 @@ public:
bool isLoaded() const { return _isLoaded; }
+ /// Asks the storage object to force overwrite to storage upon next save
+ /// even if document turned out to be changed in storage
+ void forceOverwrite() { _forceOverwrite = true; }
+
/// Returns the basic information about the file.
const FileInfo& getFileInfo() const { return _fileInfo; }
@@ -122,6 +127,7 @@ protected:
std::string _jailedFilePath;
FileInfo _fileInfo;
bool _isLoaded;
+ bool _forceOverwrite;
static bool FilesystemEnabled;
static bool WopiEnabled;
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index d1de4ab3..8b5ea409 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -269,6 +269,10 @@ close: <reason>
shutting down to let clients know they can try connecting
after a short interval.
+ * documentconflict <user name> - All sessions of this document are going down
+ because file was changed in storage and one of the user ( with <user
+ name>) asked to reload the session for all.
+
getchildid: id=<id>
Returns the child id
More information about the Libreoffice-commits
mailing list