store files that are assembled, but not sent

This commit is contained in:
konovalovsergey
2017-09-07 18:46:25 +03:00
parent 8c2b141807
commit 412ae51ebb
5 changed files with 74 additions and 10 deletions

View File

@ -60,7 +60,9 @@
"callbackRequestTimeout": 120,
"healthcheckfilepath": "../public/healthcheck.docx",
"savetimeoutdelay": 5000,
"edit_singleton": false
"edit_singleton": false,
"forgottenfiles": "forgotten",
"forgottenfilesname": "output"
},
"autoAssembly": {
"enable": false,

View File

@ -83,6 +83,7 @@ function InputCommand(data) {
this['rediskey'] = data['rediskey'];
this['nobase64'] = data['nobase64'];
this['savexfile'] = data['savexfile'];
this['forgotten'] = data['forgotten'];
} else {
this['c'] = undefined;//string command
this['id'] = undefined;//string document id
@ -123,6 +124,7 @@ function InputCommand(data) {
this['rediskey'] = undefined;
this['nobase64'] = true;
this['savexfile'] = undefined;
this['forgotten'] = undefined;
}
}
InputCommand.prototype = {
@ -249,6 +251,12 @@ InputCommand.prototype = {
setSaveKey: function(data) {
this['savekey'] = data;
},
getForgotten: function() {
return this['forgotten'];
},
setForgotten: function(data) {
this['forgotten'] = data;
},
getUserConnectionId: function() {
return this['userconnectionid'];
},

View File

@ -136,6 +136,7 @@ const cfgForceSaveEnable = config.get('autoAssembly.enable');
const cfgForceSaveInterval = ms(config.get('autoAssembly.interval'));
const cfgForceSaveStep = ms(config.get('autoAssembly.step'));
const cfgQueueRetentionPeriod = configCommon.get('queue.retentionPeriod');
const cfgForgottenFiles = config.get('server.forgottenfiles');
const redisKeySaveLock = cfgRedisPrefix + constants.REDIS_KEY_SAVE_LOCK;
const redisKeyPresenceHash = cfgRedisPrefix + constants.REDIS_KEY_PRESENCE_HASH;
@ -855,6 +856,7 @@ function* sendStatusDocument(docId, bChangeBase, userAction, callback, baseUrl,
logger.error('postData error: docId = %s;url = %s;data = %j\r\n%s', docId, uri, sendData, err.stack);
}
yield* onReplySendStatusDocument(docId, replyData);
return callback;
}
function parseReplyData(docId, replyData) {
var res = null;
@ -935,6 +937,8 @@ function* cleanDocumentOnExit(docId, deleteChanges) {
//remove changes
if (deleteChanges) {
sqlBase.deleteChanges(docId, null);
//delete forgotten after successful send on callbackUrl
yield storage.deletePath(cfgForgottenFiles + '/' + docId);
}
}
function* cleanDocumentOnExitNoChanges(docId, opt_userId) {
@ -1259,8 +1263,15 @@ exports.install = function(server, callbackFunction) {
// На всякий случай снимаем lock
yield utils.promiseRedis(redisClient, redisClient.del, redisKeySaveLock + docId);
// Send changes to save server
if (bHasChanges) {
let needSaveChanges = bHasChanges;
if (!needSaveChanges) {
//start save changes if forgotten file exists.
//more effective to send file without sfc, but this method is simpler by code
let forgotten = yield storage.listObjects(cfgForgottenFiles + '/' + docId);
needSaveChanges = forgotten.length > 0;
}
if (needSaveChanges) {
// Send changes to save server
yield* _createSaveTimer(docId, tmpUser.idOriginal);
} else {
yield* cleanDocumentOnExitNoChanges(docId, tmpUser.idOriginal);
@ -1884,6 +1895,7 @@ exports.install = function(server, callbackFunction) {
var res = true;
var docId = conn.docId;
var tmpUser = conn.user;
let hasForgotten;
if (constants.CONN_CLOSED === conn.readyState) {
//closing could happen during async action
return false;
@ -1909,7 +1921,12 @@ exports.install = function(server, callbackFunction) {
if (documentCallbackUrl) {
bindEventsRes = yield* bindEvents(docId, documentCallbackUrl, conn.baseUrl, userAction);
} else {
yield* sendStatusDocument(docId, c_oAscChangeBase.No, userAction);
let callback = yield* sendStatusDocument(docId, c_oAscChangeBase.No, userAction);
if (!callback && !bIsRestore) {
//check forgotten file
let forgotten = yield storage.listObjects(cfgForgottenFiles + '/' + docId);
hasForgotten = forgotten.length > 0;
}
}
}
@ -1944,10 +1961,10 @@ exports.install = function(server, callbackFunction) {
sendData(conn, sendObject);//Or 0 if fails
} else {
if (bIsRestore) {
yield* sendAuthInfo(undefined, undefined, conn, participantsMap);
yield* sendAuthInfo(undefined, undefined, conn, participantsMap, hasForgotten);
} else {
var objChangesDocument = yield* getDocumentChanges(docId);
yield* sendAuthInfo(objChangesDocument.arrChanges, objChangesDocument.getLength(), conn, participantsMap);
yield* sendAuthInfo(objChangesDocument.arrChanges, objChangesDocument.getLength(), conn, participantsMap, hasForgotten);
}
}
yield* publish({type: commonDefines.c_oPublishType.participantsState, docId: docId, user: tmpUser, state: true}, docId, tmpUser.id);
@ -1958,7 +1975,7 @@ exports.install = function(server, callbackFunction) {
return res;
}
function* sendAuthInfo(objChangesDocument, changesIndex, conn, participantsMap) {
function* sendAuthInfo(objChangesDocument, changesIndex, conn, participantsMap, opt_hasForgotten) {
const docId = conn.docId;
let docLock;
if(EditorTypes.document == conn.editorType){
@ -1990,6 +2007,7 @@ exports.install = function(server, callbackFunction) {
changes: objChangesDocument,
changesIndex: changesIndex,
indexUser: conn.user.indexUser,
hasForgotten: opt_hasForgotten,
jwt: cfgTokenEnableBrowser ? {token: fillJwtByConnection(conn), expires: cfgTokenSessionExpires} : undefined,
g_cAscSpellCheckUrl: cfgSpellcheckerUrl,
buildVersion: commonDefines.buildVersion,

View File

@ -57,6 +57,8 @@ var cfgImageSize = config_server.get('limits_image_size');
var cfgImageDownloadTimeout = config_server.get('limits_image_download_timeout');
var cfgRedisPrefix = config.get('services.CoAuthoring.redis.prefix');
var cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.browser');
const cfgForgottenFiles = config_server.get('forgottenfiles');
const cfgForgottenFilesName = config_server.get('forgottenfilesname');
var SAVE_TYPE_PART_START = 0;
var SAVE_TYPE_PART = 1;
@ -296,6 +298,13 @@ function* commandOpen(conn, cmd, outputData, opt_upsertRes) {
yield* getOutputData(cmd, outputData, cmd.getDocId(), row.status, row.status_info, conn);
}
} else {
let forgottenId = cfgForgottenFiles + '/' + cmd.getDocId();
let forgotten = yield storage.listObjects(forgottenId);
//replace url with forgotten file because it absorbed all lost changes
if (forgotten.length > 0) {
cmd.setUrl(undefined);
cmd.setForgotten(forgottenId);
}
//add task
cmd.setOutputFormat(constants.AVS_OFFICESTUDIO_FILE_CANVAS);
cmd.setEmbeddedFonts(false);
@ -547,6 +556,7 @@ function* commandSfcCallback(cmd, isSfcm) {
var forceSave = cmd.getForceSave();
var forceSaveType = forceSave ? forceSave.getType() : commonDefines.c_oAscForceSaveTypes.Command;
var isSfcmSuccess = false;
let storeForgotten = false;
var statusOk;
var statusErr;
if (isSfcm) {
@ -577,10 +587,15 @@ function* commandSfcCallback(cmd, isSfcm) {
outputSfc.setUserData(cmd.getUserData());
if (!isError || isErrorCorrupted) {
try {
var data = yield storage.getObject(savePathHistory);
outputSfc.setChangeHistory(JSON.parse(data.toString('utf-8')));
let forgottenId = cfgForgottenFiles + '/' + docId;
let forgotten = yield storage.listObjects(forgottenId);
if (0 === forgotten.length) {
//don't send history info because changes isn't from file in storage
var data = yield storage.getObject(savePathHistory);
outputSfc.setChangeHistory(JSON.parse(data.toString('utf-8')));
outputSfc.setChangeUrl(yield storage.getSignedUrl(getRes.baseUrl, savePathChanges));
}
outputSfc.setUrl(yield storage.getSignedUrl(getRes.baseUrl, savePathDoc));
outputSfc.setChangeUrl(yield storage.getSignedUrl(getRes.baseUrl, savePathChanges));
} catch (e) {
logger.error('Error commandSfcCallback: docId = %s\r\n%s', docId, e.stack);
}
@ -656,12 +671,24 @@ function* commandSfcCallback(cmd, isSfcm) {
updateTask.status = taskResult.FileStatus.Ok;
updateTask.statusInfo = constants.NO_ERROR;
yield taskResult.update(updateTask);
storeForgotten = true;
}
}
}
}
} else {
logger.error('Empty Callback commandSfcCallback: docId = %s', docId);
storeForgotten = true;
}
if (storeForgotten && (!isError || isErrorCorrupted)) {
try {
//todo implement storage.copy
let data = yield storage.getObject(savePathDoc);
let forgottenName = cfgForgottenFilesName + pathModule.extname(cmd.getOutputPath());
yield storage.putObject(cfgForgottenFiles + '/' + docId + '/' + forgottenName, data, data.length);
} catch (err) {
logger.error('Empty storeForgotten: docId = %s\r\n%s', docId, err.stack);
}
}
if (forceSave) {
yield* docsCoServer.setForceSave(docId, forceSave, cmd, isSfcmSuccess && !isError);

View File

@ -517,6 +517,15 @@ function* ExecuteTask(task) {
curDate = new Date();
}
yield* processDownloadFromStorage(dataConvert, cmd, task, tempDirs);
} else if (cmd.getForgotten()) {
yield* downloadFileFromStorage(cmd.getDocId(), cmd.getForgotten(), tempDirs.source);
logger.debug('downloadFileFromStorage complete(id=%s)', dataConvert.key);
let list = yield utils.listObjects(tempDirs.source, false);
if (list.length > 0) {
dataConvert.fileFrom = list[0];
} else {
error = constants.UNKNOWN;
}
} else {
error = constants.UNKNOWN;
}