Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
Simultaneous execution of `moveNote` (e.g. `renameNote`) and `saveNote` (e.g. `insertParagraph`) can cause notes to get duplicated in the underlying notebook repo due to writes based on stale data. A unit test has been attached which reproduces the issue.
Thread diagram (as executed by the unit test):
Main Thread | Thread 1 (saveNote) | Thread 2 (moveNote) |
---|---|---|
create note | ||
initiate moveNote | ||
note path & id are read | ||
trigger move in notebookRepo | ||
initiate saveNote | ||
note is read | ||
trigger save in notebookRepo | ||
notebookRepo finishes move | ||
note path of cached note is updated | ||
notebookRepo finishes save |
Since the `saveNote` thread acts on stale note data it will write the note back to its old location. Thus, after both threads have terminated, the same note with the same noteId will exist with two different paths.
The current synchronization does not prevent this issue since only `saveNote` is synchronized. Further, `loadAndProcessNote` only acquires the note's readLock, allowing both `move` and `save` threads to hold the lock at the same time.
The unit test is based on the NotebookServiceTest. To simulate delays in the underlying notebook repo that result in the thread interweaving described above a repo `VFSNotebookRepoWithDelay` has been created based on `VFSNotebookRepo` with minimal changes to simulate delays when writing files.