atomic-server icon indicating copy to clipboard operation
atomic-server copied to clipboard

Try Auto-merge when previousCommit mismatches

Open joepio opened this issue 2 years ago • 2 comments

Imagine two actors simultaneously editing the same resource. If that happens, the previousCommit will not match the lastCommit of the resource. Currently, the server will throw an Error, and the Client will try to fetch the latest state of the resource (the lastCommit) and retry the commit with the correct lastCommit value.

This works fine when updates are slow, but it falls apart when people are creating many Commits, or if the server receives a bunch of Commits in the wrong order. Things will become very slow, as the clients will have to retry a lot of these commits.

So what should happen here?

We can let the server merge commits. This basically means taking the incorrect commit, and making it correct. Change the previousCommit value, perhaps modify its contents (e.g. make sure both changes to the same property are applied), sign it again, and apply it.

This does however mean that the server will have to sign this new commit. That's a bit odd, as the server isn't an Agent in most contexts. If the merge operation is well documented and deterministic, both client and server will be able to check if it was done correctly, so we might be able to skip the signature, but since we use signatures as identifiers, it may be inconsistent to do so.

In any case, we need to make sure that the order of the applied commits can be derived by simply following the previousCommit chain.

A very simple way to deal with the errors and slowness, is to simply skip the check. But if we do this, our states become hard to replicate, and we can no longer follow the previousCommit chain.

Multiple incorrect commits

Let's consider an example of multiple commits. User is sending 5 commits, all with outdated previousCommit values, as they all depend on a chain of changes.

Ignore previousCommit

Current solution. Can lead to race conditions like #657 , which causes flaky tests when the server does not apply the commit sent last as the last one.

Only allow one commit being sent simultaneously

In git, we'd merge all these 5 commits with a 6th commit. This means the client needs to consciously make this merge. There is no auto-merge.

In our current implementation, maybe all 5 commits are currently traveling to the server. We can instead try to only send a maximum of one commit at any time.

But this approach is very limiting for various reasons. First, it doesn't fix the problem of many people making edits at the same time. Second, it will lose information if a number of individual changes are made offline, and then synced later on.

Server modifies conflicting commit

For every commit with an outdated previousCommit, the server will:

  • Find all changes since the Commit was out of sync.
  • If multiple changes are made to the same property, Calculate diffs for the commits. Merge the changes. (or not? This may be quite hard)

Server modifies only previousCommit reference

This is far simpler to realise, but it may result in weird situations:

  • Second commit totally undoing the first commit.
  • Two commits trying to remove the same property are in the history

joepio avatar May 20 '22 14:05 joepio

@joepio this issue seems to be accidentally closed by 1c25aed

rasendubi avatar May 29 '22 18:05 rasendubi

You're right, thanks! Still need a solution for this.

joepio avatar May 30 '22 07:05 joepio