-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manage concurrent edits of notes #56
Comments
@korelstar are there any updates on this? I think this issue has been described very well by you. Why not go way c) and try to merge automatically on server side and if this is impossible due conflicts 1.) first, easy step; attach the lines that could not be merged under each other (imagine like a git merge conflict) This way (only implementing an automatical merge and displaying conflicting lines under each other) the most problems could be solved (at least i believe that most "conflicts" should be mergable automatically). At least there is no more data loss. |
Yep, too bad that we haven't implemented this yet. But for the web app, this will be fixed by implementing #331. However, this wouldn't be a solution for the Android app. So I'm unsure, which way we should go for the Android app. Of course, we could go the way I described in the initial posting, here. But we can't do step 2 before step 1. What I described under c) has to be done on the client, since the server has the current note, only. The server has no information about the note state before the mobile client changed it. Hence, the server can't create a diff of those changes. But this is required in order to apply these changes on the current state. Ergo: The server part is easy to implement, I'd love to do this! But the hard part is in the Android app. So if you would like to take over this part, let's start it! 😀 When you will really start, please ping me, I have some ideas on implementing the backend in the Android app that I could share. |
I disagree, the server has the new content. As soon as i |
Yes, of course. But the server doesn't know from which state the mobile user has made his changes. This is required to gather the diff from those changes. Then these changes can be applied to the current state from server. Otherwise, the server can't merge the changes, it can only overwrite the changes with those from the mobile user (like it is currently implemented). |
Finally, I've implemented this: please have a look at #692 ! Third-party clients have to implement their part, though. |
Currently, we have no proper handling of concurrent edits. Those can happen in many scenarios and it results in lost updates:
Scenario 1: Shared notes
Scenario 2: Mobile clients
I would like to improve this situation and I thought about a strategy how to cope with this. We are experiencing a classical lost update problem, due to a write-write-conflict. Traditional databases use locking to prevent this. However, in our situation, we have a distributed system, where locking is not appropriate. Instead, I would propose to use optimistic concurrency control. This means, we allow always editing and try to resolve conflicts later on.
To do this, two steps are needed: 1.) Identify conflicts, and 2.) Resolve conflicts.
1. Identify conflicts
In order to check, if a note has been changed in the meanwhile (from getting the current state from the server to putting the changed data back to the server) we could use the ETags I proposed in #49 (in summary: it represents the state of the note by using a checksum over all attributes).
The client (mobile client or web app) has to save the current ETag for each note and update it on every synchronization (this is required for #49, too). When the note is edited, the client sends the HTTP header
If-Match: "etag"
. The server (i.e.NotesController
resp.NotesAPIController
) checks if the ETag from the HTTP request header matches the current ETag from filesystem/database. If true, the note is changed and sent back to the client. If not, the server sends the HTTP response code412 Precondition Failed
and the current server state of the note in the body of the response. The client now sees that the note has changed in the meanwhile and resolves the write-write-conflict (see 2.)).These changes are totally backwards-compatible and conform to the HTTP protocol.
2. Resolve conflicts:
The client now has data from local changes and remote changes and has to do something. This is harder than the first step and multiple reactions are possible.
a) Let the user decide: ask the user whether i) overwrite local changes, ii) overwrite remote changes, or iii) save local (or remote) changes as new note.
b) Let the user merge: provide an interface which allows for merging the files (you know it from your version control).
c) Try to merge automatically: merge all changes automatically, e.g. using the google-diff-match-patch (Demo, Code) library.
I think, user interaction has to be avoided, so I'm preferring c), but I don't know if this will always work.
However, I wanted to write down my thoughts on this so that everybody can participate on a discussion on this. The first step is easy to implement and must be done in this app (controller). The second step is much more comprehensive and requires changes on those clients (i.e. this app, Android app, iOS app) which should be concurrency-save.
Any comments are welcome :-)
How high do you would estimate the importance of this issue?
Does nextcloud/server (resp. its clients like nextcloud/android and desktop clients) deal with this issue?
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: