mirror of https://github.com/laurent22/joplin.git
All: Fixed race condition when a note is being uploaded while it's being modified in the text editor
parent
29f14681a8
commit
78ce10ddf0
|
@ -830,6 +830,8 @@ describe('Synchronizer', function() {
|
|||
}));
|
||||
|
||||
it('should sync resources', asyncTest(async () => {
|
||||
while (insideBeforeEach) await time.msleep(100);
|
||||
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
|
|
|
@ -167,7 +167,7 @@ class NoteTextComponent extends React.Component {
|
|||
async componentWillReceiveProps(nextProps) {
|
||||
if ('noteId' in nextProps && nextProps.noteId !== this.props.noteId) {
|
||||
await this.reloadNote(nextProps);
|
||||
if(this.editor_){
|
||||
if (this.editor_){
|
||||
const session = this.editor_.editor.getSession();
|
||||
const undoManager = session.getUndoManager();
|
||||
undoManager.reset();
|
||||
|
|
|
@ -83,6 +83,7 @@ class DecryptionWorker {
|
|||
});
|
||||
continue;
|
||||
}
|
||||
this.logger().warn('DecryptionWorker: error for: ' + item.id + ' (' + ItemClass.tableName() + ')');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,9 +320,23 @@ class Synchronizer {
|
|||
}
|
||||
}
|
||||
|
||||
// Note: Currently, we set sync_time to update_time, which should work fine given that the resolution is the millisecond.
|
||||
// In theory though, this could happen:
|
||||
//
|
||||
// 1. t0: Editor: Note is modified
|
||||
// 2. t0: Sync: Found that note was modified so start uploading it
|
||||
// 3. t0: Editor: Note is modified again
|
||||
// 4. t1: Sync: Note has finished uploading, set sync_time to t0
|
||||
//
|
||||
// Later any attempt to sync will not detect that note was modified in (3) (within the same millisecond as it was being uploaded)
|
||||
// because sync_time will be t0 too.
|
||||
//
|
||||
// The solution would be to use something like an etag (a simple counter incremented on every change) to make sure each
|
||||
// change is uniquely identified. Leaving it like this for now.
|
||||
|
||||
if (canSync) {
|
||||
await this.api().setTimestamp(path, local.updated_time);
|
||||
await ItemClass.saveSyncTime(syncTargetId, local, time.unixMs());
|
||||
await ItemClass.saveSyncTime(syncTargetId, local, local.updated_time);
|
||||
}
|
||||
|
||||
} else if (action == 'itemConflict') {
|
||||
|
|
Loading…
Reference in New Issue