Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix a race condition that leads to a CouchDB conflict (#4158)
If Alice and Bob shares a file within a Cozy to Cozy sharing. The file is present on both cozy instances, and the two users make a change on this file concurrently. For example, Alice adds the file to a photo album, and Bob renames it. A race condition may happen when Bob's instance sends its update to Alice's instance. The CouchDB document will then been saved in CouchDB with a conflict (two leaf revisions). ``` +----------------------------------+----------------------------------+ | Goroutine A | Goroutine B | | Add the file to an album | Share-replicate sends the rename | +----------------------------------+----------------------------------+ | | 1. Load the file from CouchDB | | 2. Load the file from CouchDB | | | 3. Get the VFS lock | | | 4. Save the file with rev 2-aaa | | | 5. Release the VFS lock | | | | 6. Get the VFS lock | | | 7. Save the file with rev 2-bbb | | | 8. Release the VFS lock | +----------------------------------+----------------------------------+ ``` In general, it is not possible to save a document with a revision 2-bbb, when the document is already at revision 2-aaa: CouchDB responds with a 409 Conflict. But, the share-track is doing a bulk update with the option new_edit: false. This is done because the replication process needs to force the same revision on Alice's Cozy that it is on Bob's Cozy. But, it also enable to create a conflict in CouchDB. The fix is to reload the file between the steps 6 and 7 (when the VFS lock has been acquired), and check that the revision has not changed. It would be nice to load the document when the VFS lock is acquired, but it is not possible currently because of how the code is organized.
- Loading branch information