mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-04-07 14:04:35 +08:00
for forceSave button
This commit is contained in:
@ -57,9 +57,10 @@
|
||||
"savetimeoutdelay": 5000,
|
||||
"edit_singleton": false
|
||||
},
|
||||
"forcesave": {
|
||||
"timeout": "0",
|
||||
"quantum": "1m",
|
||||
"autoAssembly": {
|
||||
"enable": true,
|
||||
"intervalWithoutChanges": "1m",
|
||||
"checkInterval": "1m",
|
||||
"minRetentionPeriod": "1m"
|
||||
},
|
||||
"utils": {
|
||||
|
||||
@ -28,6 +28,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoAssembly": {
|
||||
"enable": false
|
||||
},
|
||||
"utils": {
|
||||
"utils_common_fontdir": "C:\\Windows\\Fonts"
|
||||
},
|
||||
|
||||
@ -568,6 +568,7 @@ function OutputSfcData() {
|
||||
this['userdata'] = undefined;
|
||||
this['lastsave'] = undefined;
|
||||
this['notmodified'] = undefined;
|
||||
this['forcesavetype'] = undefined;
|
||||
}
|
||||
OutputSfcData.prototype.getKey = function() {
|
||||
return this['key'];
|
||||
@ -635,6 +636,12 @@ OutputSfcData.prototype.getNotModified = function() {
|
||||
OutputSfcData.prototype.setNotModified = function(v) {
|
||||
this['notmodified'] = v;
|
||||
};
|
||||
OutputSfcData.prototype.getForceSaveType = function() {
|
||||
return this['forcesavetype']
|
||||
};
|
||||
OutputSfcData.prototype.setForceSaveType = function(v) {
|
||||
this['forcesavetype'] = v;
|
||||
};
|
||||
|
||||
function OutputMailMerge(mailMergeSendData) {
|
||||
if (mailMergeSendData) {
|
||||
|
||||
@ -129,8 +129,9 @@ const cfgTokenSessionExpires = ms(config.get('token.session.expires'));
|
||||
const cfgTokenInboxHeader = config.get('token.inbox.header');
|
||||
const cfgTokenInboxPrefix = config.get('token.inbox.prefix');
|
||||
const cfgSecretSession = config.get('secret.session');
|
||||
const cfgForceSaveTimeout = ms(config.get('forcesave.timeout'));
|
||||
const cfgForceSaveMinExpiration = ms(config.get('forcesave.minRetentionPeriod'));
|
||||
const cfgForceSaveEnable = config.get('autoAssembly.enable');
|
||||
const cfgForceSaveTimeout = ms(config.get('autoAssembly.intervalWithoutChanges'));
|
||||
const cfgForceSaveMinExpiration = ms(config.get('autoAssembly.minRetentionPeriod'));
|
||||
const cfgQueueRetentionPeriod = configCommon.get('queue.retentionPeriod');
|
||||
|
||||
const redisKeySaveLock = cfgRedisPrefix + constants.REDIS_KEY_SAVE_LOCK;
|
||||
@ -532,7 +533,7 @@ function* isUserReconnect(docId, userId, connectionId) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function* publish(data, optDocId, optUserId) {
|
||||
function* publish(data, optDocId, optUserId, opt_pubsub) {
|
||||
var needPublish = true;
|
||||
if(optDocId && optUserId) {
|
||||
needPublish = false;
|
||||
@ -547,7 +548,8 @@ function* publish(data, optDocId, optUserId) {
|
||||
}
|
||||
if(needPublish) {
|
||||
var msg = JSON.stringify(data);
|
||||
pubsub.publish(msg);
|
||||
var realPubsub = opt_pubsub ? opt_pubsub : pubsub;
|
||||
realPubsub.publish(msg);
|
||||
}
|
||||
}
|
||||
function* addTask(data, priority, opt_queue, opt_expiration) {
|
||||
@ -663,17 +665,14 @@ function* setForceSave(docId, forceSave, cmd, success) {
|
||||
let forceSaveIndex = getForceSaveIndex(forceSave.getTime(), forceSave.getIndex());
|
||||
if (success) {
|
||||
yield utils.promiseRedis(redisClient, redisClient.hset, redisKeyForceSave + docId, forceSaveIndex, true);
|
||||
|
||||
let forceSaveType = forceSave.getType();
|
||||
if (cfgForceSaveTimeout > 0 || commonDefines.c_oAscForceSaveTypes.Button === forceSaveType) {
|
||||
yield* publish({
|
||||
type: commonDefines.c_oPublishType.forceSave, docId: docId,
|
||||
data: {type: forceSaveType, time: forceSave.getTime()}
|
||||
}, cmd.getUserConnectionId());
|
||||
}
|
||||
} else {
|
||||
yield utils.promiseRedis(redisClient, redisClient.hdel, redisKeyForceSave + docId, forceSaveIndex);
|
||||
}
|
||||
let forceSaveType = forceSave.getType();
|
||||
yield* publish({
|
||||
type: commonDefines.c_oPublishType.forceSave, docId: docId,
|
||||
data: {type: forceSaveType, time: forceSave.getTime(), success: success}
|
||||
}, cmd.getUserConnectionId());
|
||||
}
|
||||
function* getLastForceSave(docId, lastSave) {
|
||||
let res = false;
|
||||
@ -686,7 +685,7 @@ function* getLastForceSave(docId, lastSave) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function* startForceSave(docId, type, opt_userdata, opt_userConnectionId, opt_baseUrl, opt_queue) {
|
||||
function* startForceSave(docId, type, opt_userdata, opt_userConnectionId, opt_baseUrl, opt_queue, opt_pubsub) {
|
||||
logger.debug('startForceSave start:docId = %s', docId);
|
||||
let res = {code: commonDefines.c_oAscServerCommandErrors.NoError, time: null};
|
||||
let lastSave = null;
|
||||
@ -713,6 +712,13 @@ function* startForceSave(docId, type, opt_userdata, opt_userConnectionId, opt_ba
|
||||
let forceSave = new commonDefines.CForceSaveData(lastSave);
|
||||
forceSave.setType(type);
|
||||
|
||||
if (commonDefines.c_oAscForceSaveTypes.Button !== type) {
|
||||
yield* publish({
|
||||
type: commonDefines.c_oPublishType.forceSave, docId: docId,
|
||||
data: {type: type, time: forceSave.getTime(), start: true}
|
||||
}, undefined, undefined, opt_pubsub);
|
||||
}
|
||||
|
||||
let priority;
|
||||
let expiration;
|
||||
if (commonDefines.c_oAscForceSaveTypes.Timeout === type) {
|
||||
@ -1952,18 +1958,6 @@ exports.install = function(server, callbackFunction) {
|
||||
return JSON.parse(val);
|
||||
});
|
||||
}
|
||||
let lastForceSaveTime = null;
|
||||
if (cfgForceSaveTimeout > 0) {
|
||||
lastForceSaveTime = -1;
|
||||
//todo multi with messages
|
||||
let lastSave = yield* getLastSave(docId);
|
||||
if (lastSave) {
|
||||
let notModified = yield* getLastForceSave(docId, lastSave);
|
||||
if (notModified) {
|
||||
lastForceSaveTime = lastSave.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
const sendObject = {
|
||||
type: 'auth',
|
||||
result: 1,
|
||||
@ -1977,7 +1971,6 @@ exports.install = function(server, callbackFunction) {
|
||||
indexUser: conn.user.indexUser,
|
||||
jwt: cfgTokenEnableBrowser ? {token: fillJwtByConnection(conn), expires: cfgTokenSessionExpires} : undefined,
|
||||
g_cAscSpellCheckUrl: cfgSpellcheckerUrl,
|
||||
lastForceSaveTime: lastForceSaveTime,
|
||||
buildVersion: commonDefines.buildVersion,
|
||||
buildNumber: commonDefines.buildNumber
|
||||
};
|
||||
@ -2211,7 +2204,7 @@ exports.install = function(server, callbackFunction) {
|
||||
'baseUrl', utils.getBaseUrlByConnection(conn)],
|
||||
['expire', redisKeyLastSave + docId, cfgExpLastSave]
|
||||
];
|
||||
if (cfgForceSaveTimeout > 0) {
|
||||
if (cfgForceSaveEnable) {
|
||||
let expireAt = new Date().getTime() + cfgForceSaveTimeout;
|
||||
commands.push(['zadd', redisKeyForceSaveTimeout, expireAt, docId]);
|
||||
}
|
||||
|
||||
@ -515,13 +515,15 @@ function* commandSfcCallback(cmd, isSfcm) {
|
||||
logger.debug('Start commandSfcCallback: docId = %s', docId);
|
||||
var saveKey = cmd.getSaveKey();
|
||||
var statusInfo = cmd.getStatusInfo();
|
||||
var isError = constants.NO_ERROR != statusInfo && constants.CONVERT_CORRUPTED != statusInfo;
|
||||
var isError = constants.NO_ERROR != statusInfo;
|
||||
var isErrorCorrupted = constants.CONVERT_CORRUPTED == statusInfo;
|
||||
var savePathDoc = saveKey + '/' + cmd.getOutputPath();
|
||||
var savePathChanges = saveKey + '/changes.zip';
|
||||
var savePathHistory = saveKey + '/changesHistory.json';
|
||||
var getRes = yield* docsCoServer.getCallback(docId);
|
||||
var forceSave = cmd.getForceSave();
|
||||
var forceSaveType = forceSave ? forceSave.getType() : commonDefines.c_oAscForceSaveTypes.Command;
|
||||
var isSfcmSuccess = false;
|
||||
var statusOk;
|
||||
var statusErr;
|
||||
if (isSfcm) {
|
||||
@ -550,7 +552,7 @@ function* commandSfcCallback(cmd, isSfcm) {
|
||||
outputSfc.setActions(actions);
|
||||
}
|
||||
outputSfc.setUserData(cmd.getUserData());
|
||||
if (!isError) {
|
||||
if (!isError || isErrorCorrupted) {
|
||||
try {
|
||||
var data = yield storage.getObject(savePathHistory);
|
||||
outputSfc.setChangeHistory(JSON.parse(data.toString('utf-8')));
|
||||
@ -574,19 +576,16 @@ function* commandSfcCallback(cmd, isSfcm) {
|
||||
var row = selectRes.length > 0 ? selectRes[0] : null;
|
||||
//send only if FileStatus.Ok to prevent forcesave after final save
|
||||
if (row && row.status == taskResult.FileStatus.Ok) {
|
||||
if (forceSave && !isError) {
|
||||
if (forceSave) {
|
||||
outputSfc.setForceSaveType(forceSaveType);
|
||||
outputSfc.setLastSave(new Date(forceSave.getTime()).toISOString());
|
||||
}
|
||||
var resSend = true;
|
||||
try {
|
||||
yield* docsCoServer.sendServerRequest(docId, uri, outputSfc);
|
||||
isSfcmSuccess = true;
|
||||
} catch (err) {
|
||||
resSend = false;
|
||||
logger.error('sendServerRequest error: docId = %s;url = %s;data = %j\r\n%s', docId, uri, outputSfc, err.stack);
|
||||
}
|
||||
if (forceSave) {
|
||||
yield* docsCoServer.setForceSave(docId, forceSave, cmd, resSend);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//if anybody in document stop save
|
||||
@ -641,6 +640,9 @@ function* commandSfcCallback(cmd, isSfcm) {
|
||||
} else {
|
||||
logger.error('Empty Callback commandSfcCallback: docId = %s', docId);
|
||||
}
|
||||
if (forceSave) {
|
||||
yield* docsCoServer.setForceSave(docId, forceSave, cmd, isSfcmSuccess && !isError);
|
||||
}
|
||||
if (docsCoServer.getIsShutdown() && !isSfcm) {
|
||||
yield utils.promiseRedis(redisClient, redisClient.srem, redisKeyShutdown, docId);
|
||||
}
|
||||
|
||||
@ -46,13 +46,14 @@ var constants = require('./../../Common/sources/constants');
|
||||
var commondefines = require('./../../Common/sources/commondefines');
|
||||
var pubsubRedis = require('./pubsubRedis.js');
|
||||
var queueService = require('./../../Common/sources/taskqueueRabbitMQ');
|
||||
var pubsubService = require('./' + config.get('pubsub.name'));
|
||||
|
||||
var cfgRedisPrefix = config.get('redis.prefix');
|
||||
var cfgExpFilesCron = config.get('expire.filesCron');
|
||||
var cfgExpDocumentsCron = config.get('expire.documentsCron');
|
||||
var cfgExpFiles = config.get('expire.files');
|
||||
var cfgExpFilesRemovedAtOnce = config.get('expire.filesremovedatonce');
|
||||
var cfgForceSaveTimeoutQuantum = ms(config.get('forcesave.quantum'));
|
||||
var cfgForceSaveTimeoutQuantum = ms(config.get('autoAssembly.checkInterval'));
|
||||
|
||||
var redisKeyDocuments = cfgRedisPrefix + constants.REDIS_KEY_DOCUMENTS;
|
||||
var redisForceSaveTimeout = cfgRedisPrefix + constants.REDIS_KEY_FORCE_SAVE_TIMEOUT;
|
||||
@ -138,6 +139,7 @@ var checkDocumentExpire = function() {
|
||||
let forceSaveTimeout = function() {
|
||||
return co(function* () {
|
||||
let queue = null;
|
||||
let pubsub = null;
|
||||
try {
|
||||
logger.debug('forceSaveTimeout start');
|
||||
let redisClient = pubsubRedis.getClientRedis();
|
||||
@ -153,18 +155,22 @@ let forceSaveTimeout = function() {
|
||||
queue = new queueService();
|
||||
yield queue.initPromise(true, false, false, false);
|
||||
|
||||
pubsub = new pubsubService();
|
||||
yield pubsub.initPromise();
|
||||
|
||||
let actions = [];
|
||||
for (let i = 0; i < expiredKeys.length; ++i) {
|
||||
let docId = expiredKeys[i];
|
||||
if (docId) {
|
||||
let action = yield docsCoServer.startForceSavePromise(docId, commondefines.c_oAscForceSaveTypes.Timeout,
|
||||
undefined, undefined, undefined, queue);
|
||||
undefined, undefined, undefined, queue, pubsub);
|
||||
actions.push(action);
|
||||
}
|
||||
}
|
||||
yield Promise.all(actions);
|
||||
logger.debug('forceSaveTimeout actions.length %d', actions.length);
|
||||
}
|
||||
logger.debug('forceSaveTimeout end');
|
||||
} catch (e) {
|
||||
logger.error('forceSaveTimeout error:\r\n%s', e.stack);
|
||||
} finally {
|
||||
@ -172,6 +178,9 @@ let forceSaveTimeout = function() {
|
||||
if (queue) {
|
||||
yield queue.close();
|
||||
}
|
||||
if (pubsub) {
|
||||
yield pubsub.close();
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('checkDocumentExpire error:\r\n%s', e.stack);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user