Fix checkpoint issues in onlyoffice

pull/1/head
yflory 5 years ago
parent 4484cda9b6
commit 7254d093a3

@ -9,7 +9,7 @@ www/common/onlyoffice/sdkjs
www/common/onlyoffice/web-apps www/common/onlyoffice/web-apps
www/common/onlyoffice/x2t www/common/onlyoffice/x2t
www/common/onlyoffice/v1 www/common/onlyoffice/v1
www/common/onlyoffice/v2 www/common/onlyoffice/v2*
server.js server.js
www/common/old-media-tag.js www/common/old-media-tag.js

@ -278,6 +278,7 @@ define([
}; };
var onUploaded = function (ev, data, err) { var onUploaded = function (ev, data, err) {
content.saveLock = undefined;
if (err) { if (err) {
console.error(err); console.error(err);
return void UI.alert(Messages.oo_saveError); return void UI.alert(Messages.oo_saveError);
@ -289,7 +290,6 @@ define([
index: ev.index index: ev.index
}; };
oldHashes = JSON.parse(JSON.stringify(content.hashes)); oldHashes = JSON.parse(JSON.stringify(content.hashes));
content.saveLock = undefined;
// If this is a migration, set the new version // If this is a migration, set the new version
if (APP.migrate) { if (APP.migrate) {
delete content.migration; delete content.migration;
@ -328,6 +328,9 @@ define([
sframeChan.query('Q_OO_SAVE', data, function (err) { sframeChan.query('Q_OO_SAVE', data, function (err) {
onUploaded(ev, data, err); onUploaded(ev, data, err);
}); });
},
onError: function (err) {
onUploaded(null, null, err);
} }
}; };
APP.FM = common.createFileManager(fmConfig); APP.FM = common.createFileManager(fmConfig);
@ -347,24 +350,19 @@ define([
var makeCheckpoint = function (force) { var makeCheckpoint = function (force) {
if (!common.isLoggedIn()) { return; } if (!common.isLoggedIn()) { return; }
var locked = content.saveLock; var locked = content.saveLock;
var lastCp = getLastCp();
var needCp = force || ooChannel.cpIndex % CHECKPOINT_INTERVAL === 0 ||
(ooChannel.cpIndex - lastCp.index) > CHECKPOINT_INTERVAL;
if (!needCp) { return; }
if (!locked || !isUserOnline(locked) || force) { if (!locked || !isUserOnline(locked) || force) {
content.saveLock = myOOId; content.saveLock = myOOId;
APP.onLocal(); APP.onLocal();
APP.realtime.onSettle(function () { APP.realtime.onSettle(function () {
saveToServer(); saveToServer();
}); });
return;
} }
// The save is locked by someone else. If no new checkpoint is created
// in the next 20 to 40 secondes and the lock is kept by the same user,
// force the lock and make a checkpoint.
var saved = stringify(content.hashes);
var to = 20000 + (Math.random() * 20000);
setTimeout(function () {
if (stringify(content.hashes) === saved && locked === content.saveLock) {
makeCheckpoint(force);
}
}, to);
}; };
var restoreLastCp = function () { var restoreLastCp = function () {
content.saveLock = myOOId; content.saveLock = myOOId;
@ -378,6 +376,23 @@ define([
}); });
}); });
}; };
// Add a timeout to check if a checkpoint was correctly saved by the locking user
// and "unlock the sheet" or "make a checkpoint" if needed
var cpTo;
var checkCheckpoint = function () {
clearTimeout(cpTo);
var saved = stringify(content.hashes);
var locked = content.saveLock;
var to = 20000 + (Math.random() * 20000);
cpTo = setTimeout(function () {
// If no checkpoint was added and the same user still has the lock
// then make a checkpoint if needed (cp interval)
if (stringify(content.hashes) === saved && locked === content.saveLock) {
content.saveLock = undefined;
makeCheckpoint();
}
}, to);
};
var openRtChannel = function (cb) { var openRtChannel = function (cb) {
@ -684,11 +699,7 @@ define([
ooChannel.cpIndex++; ooChannel.cpIndex++;
ooChannel.lastHash = hash; ooChannel.lastHash = hash;
// Check if a checkpoint is needed // Check if a checkpoint is needed
var lastCp = getLastCp();
if (common.isLoggedIn() && (ooChannel.cpIndex % CHECKPOINT_INTERVAL === 0 ||
(ooChannel.cpIndex - lastCp.index) > CHECKPOINT_INTERVAL)) {
makeCheckpoint(); makeCheckpoint();
}
// Remove my lock // Remove my lock
delete content.locks[getId()]; delete content.locks[getId()];
oldLocks = JSON.parse(JSON.stringify(content.locks)); oldLocks = JSON.parse(JSON.stringify(content.locks));
@ -1546,6 +1557,16 @@ define([
} }
} }
// If the sheet is locked by an offline user, remove it
if (content && content.saveLock && !isUserOnline(content.saveLock)) {
content.saveLock = undefined;
APP.onLocal();
} else if (content && content.saveLock) {
// If someone is currently creating a checkpoint (and locking the sheet),
// make sure it will end (maybe you'll have to make the checkpoint yourself)
checkCheckpoint();
}
var s = h('script', { var s = h('script', {
type:'text/javascript', type:'text/javascript',
src: '/common/onlyoffice/'+version+'web-apps/apps/api/documents/api.js' src: '/common/onlyoffice/'+version+'web-apps/apps/api/documents/api.js'
@ -1575,6 +1596,7 @@ define([
}; };
var reloadPopup = false; var reloadPopup = false;
config.onRemote = function () { config.onRemote = function () {
if (initializing) { return; } if (initializing) { return; }
var userDoc = APP.realtime.getUserDoc(); var userDoc = APP.realtime.getUserDoc();
@ -1589,9 +1611,11 @@ define([
content = json.content; content = json.content;
if (!wasLocked && content.saveLock) { if (content.saveLock && wasLocked !== content.saveLock) {
// Someone is creating a new checkpoint: fix the sheets ids // Someone new is creating a checkpoint: fix the sheets ids
fixSheets(); fixSheets();
// If the checkpoint is not saved in 20s to 40s, do it ourselves
checkCheckpoint();
} }
if (content.hashes) { if (content.hashes) {

@ -162,6 +162,9 @@ define([
// then we could check if a file is too large without going to the server... // then we could check if a file is too large without going to the server...
queue.inProgress = false; queue.inProgress = false;
queue.next(); queue.next();
if (config.onError) { config.onError(e); }
if (e === 'TOO_LARGE') { if (e === 'TOO_LARGE') {
$pv.text(Messages.upload_tooLargeBrief); $pv.text(Messages.upload_tooLargeBrief);
return void UI.alert(Messages.upload_tooLarge); return void UI.alert(Messages.upload_tooLarge);

Loading…
Cancel
Save