Skip to content
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

WNFS Conflict Resolution #163

Open
Tracked by #501
expede opened this issue Jan 13, 2021 · 6 comments
Open
Tracked by #501

WNFS Conflict Resolution #163

expede opened this issue Jan 13, 2021 · 6 comments
Assignees
Labels
🧭 critical path enhancement New feature or request

Comments

@expede
Copy link
Member

expede commented Jan 13, 2021

NB: Feature requests will only be considered if they solve a pain

Summary

Problem

Concurrent updates across devices can cause data loss by:

  1. Dropping history (overwriting revisions)
  2. Forgetting files in the latest generation when reconciling with new data

There is a server-side conflict detection portion of this, but the front end needs to know how to reconcile changes first.

Impact

Sometimes users loose recent changes or files

Solution

"Rebase" changes of the local WNFS on top of a remote source of truth at a conflict point.

This means being able to "pop off" the changes since the last common CID, and place them on top of the latest CID from the single source of truth.

The one wrinkle is that we don't want to loose any new files, so this needs to add any missing links back to the new CID head, and propagate those through the history. If you recall this image:

Screen Shot 2021-01-12 at 9 35 08 PM

We're keeping the blue boxes (new files), but adjusting the blue lines to point to all existing files at the previous step.

Not that this does not include sub-file merging. We cannot understand their content structure ahead of time, and even then it often goes awry. Complete individual files can be overwritten, and we keep the history if they want the old copy or to do manual merging of the inner contents.

@matheus23
Copy link
Contributor

There is a server-side conflict detection portion of this, but the front end needs to know how to reconcile changes first.

I think there's value in implementing the server-side portion of this without implementing the front-end change reconciling in webnative. E.g. I could already implement conflict resolution on the app layer in flatmate if the server-side portion existed!

At the moment I can't do this, as any .publish call might overwrite any changes made by anyone else. So I'd need some kind of .publishIfTheServerAgreesWithMeThatTheMostRecentStateWas(cid). 😄

@expede
Copy link
Member Author

expede commented Mar 30, 2021

There is a server-side conflict detection portion of this, but the front end needs to know how to reconcile changes first.

I think there's value in implementing the server-side portion of this without implementing the front-end change reconciling in webnative. E.g. I could already implement conflict resolution on the app layer in flatmate if the server-side portion existed!

At the moment I can't do this, as any .publish call might overwrite any changes made by anyone else. So I'd need some kind of .publishIfTheServerAgreesWithMeThatTheMostRecentStateWas(cid). 😄

Right, or you could ask for the latest head before you apply your changes with the GET /user/data/{username} endpoint

You'll need to do the reconciliation in either case. Just knowing that you're behind only gets you so far, you still need WNFS to merge the changes, or to do them yourself manually. Having the remote block you from pushing breaks everything unless you know how to make a proper WNFS rebase, which is equivalent to building this feature in the FE.

@matheus23
Copy link
Contributor

Right, or you could ask for the latest head before you apply your changes with the GET /user/data/{username} endpoint

That's my plan for now. It just leaves an uneasy feeling as two concurrent GET + PATCH requests can race each other.

@expede expede assigned agentofuser and unassigned agentofuser May 5, 2021
@expede expede modified the milestones: CRDT, 🧭 Critical Path Oct 26, 2021
@expede expede assigned matheus23 and unassigned dholms Oct 26, 2021
@expede expede removed this from the 🧭 Critical Path milestone Oct 26, 2021
@expede expede added enhancement New feature or request 🧭 critical path labels Oct 26, 2021
@expede expede added this to the 🕊 Conflict Resolution milestone Nov 10, 2021
@jeffgca
Copy link
Contributor

jeffgca commented Jun 3, 2022

@appcypher @matheus23 is this going into rs-winfs?

@appcypher
Copy link
Contributor

@appcypher @matheus23 is this going into rs-winfs?

I believe so. This sounds very much like the file tree merge issue that is expected to be solved at some point in the future.

@matheus23
Copy link
Contributor

is this going into rs-winfs?

Yes it is! Also reminds me to retract what I said previously:

Right, or you could ask for the latest head before you apply your changes with the GET /user/data/{username} endpoint

That's my plan for now. It just leaves an uneasy feeling as two concurrent GET + PATCH requests can race each other.

I don't think that's an issue! We don't actually need atomic writes to the head pointer! It's the magic of CRDTs. If you accidentally race with someone else, you'll be able to figure that out on your next data root fetch and be able to fix the issues that came because of that. Yay immutable history and merkle clocks! :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧭 critical path enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants