Is there an example somewhere of implementing conf...
# store
r
Is there an example somewhere of implementing conflict resolution with Store5? The docs say that the Mutable Store "Conflict Resolution: Works with the Bookkeeper and Updater to resolve conflicts that arise from concrruent modifications or offline changes.". However, its unclear to me how it does this? I'm not seeing the relevant API surface. I want to implement a conflict resolution mechanism that combines data from the conflicted entities to create a new entity.
m
Currently Store5 defers actual handling of conflicts to server. The Mutable Store will check with the Bookkeeper to see if any conflicts might exist. If a conflict might exist, Mutable Store will use the Updater to push the latest local value. After pushing the latest value, the Mutable Store delegates pulling to the Store which uses the Fetcher. Can you tell me more why you want to handle combining data on the client, rather than server? In general, I’d recommend moving that resolution logic to the backend for supporting multiple devices and platforms
r
> Currently Store5 defers actual handling of conflicts to server… Can you tell me more why you want to handle combining data on the client, rather than server? In general, I’d recommend moving that resolution logic to the backend for supporting multiple devices and platforms That makes a lot of sense, and is in line with my overall design, which does indeed do conflict resolution the server. After re-reading your message and looking at the source, I think I understand how it works now, but confirmation of my understanding would be great. See below. > The Mutable Store will check with the Bookkeeper to see if any conflicts might exist. I guess this is checking if a value that was retrieved from the server has the same key as a value in the bookkeeper that failed to synchronize to the server. If there is, the bookkeeper tries to resolve that conflict (
tryEagerlyResolveConflicts
) by sending the value that failed to sync to the server again via the Updater, and then fetching the value back to get the new value after the server has resolved the conflict via the Fetcher. Is that right? This leads me to another question. Who is responsible for sending / retrying the failed bookkeeper values in general? I don't see any way in the Bookkeeper API to retrieve a collection of these so I guess my application code is responsible for retrieving them from my local db directly, and then periodically sending them to the server via the Updater according to my own retry policies? Maybe the piece I'm missing is understanding clearly the responsibilities of Store vs my own application code, with respect to the Bookkeeper.
m
I guess this is checking if a value that was retrieved from the server has the same key as a value in the bookkeeper that failed to synchronize to the server.
The Bookkeeper only knows about timestamps (any failed sync, whether it's a failed creation, update, delete).
If there is, the bookkeeper tries to resolve that conflict (
tryEagerlyResolveConflicts
)
As above the Bookkeeper only knows about timestamps. It's a DAO for timestamps of failed syncs. The MutableStore is the class coordinating the Bookkeeper and Updater. It also coordinates the SourceOfTruth and Fetcher indirectly by delegating to the Store. Store handles reads, MutableStore handles writes. So, it's not that the bookkeeper is tracking failed syncs and trying to resolve them. It's that the MutableStore is checking with the bookkeeper to see if there are any unresolved failed syncs. An unresolved failed sync exists if the bookkeeper has a timestamp for the given input.
by sending the value that failed to sync to the server again via the Updater
If there is an unresolved failed sync, the MutableStore will try to eagerly resolve that failed sync. It does that not by pushing a specific value, but by getting the latest value from the SourceOfTruth and pushing that.
and then fetching the value back to get the new value after the server has resolved the conflict via the Fetcher.
Yes, after the latest value is pushed, the MutableStore will delegate to the Store to pull the latest value from network using Fetcher. One note here is that I'm not really in love with our current implementation of trying to resolve conflicts. What I'm not in love with is that if the network request pushing the latest value fails, we still go ahead and pull the latest value from the network. There's an open TODO to make this more configurable: https://github.com/MobileNativeFoundation/Store/pull/674/files#diff-9c94abdd3eb75cadd156028635c73fc99a9c046ed117345c3819d891d3d19613R45-R47
Who is responsible for sending / retrying the failed bookkeeper values in general? I don't see any way in the Bookkeeper API to retrieve a collection of these
The MutableStore. Every time the MutableStore receives a request to read data from the network, it will first check with the Bookkeeper and then handle accordingly.
so I guess my application code is responsible for retrieving them from my local db directly, and then periodically sending them to the server via the Updater according to my own retry policies?
You shouldn't need to do this, but lmk if you feel like you do. Right now, the MutableStore will check for potential conflicts on every read attempt. I think that should be sufficient mostly, but would be interested to learn of exceptions
r
The MutableStore. Every time the MutableStore receives a request to read data from the network, it will first check with the Bookkeeper and then handle accordingly.
You shouldn't need to do this, but lmk if you feel like you do.
Is it any request to read data from the network, or is it only requests that match any of the failed keys? If the latter, my main worry would be that a value may sit for too long on the client without being sent to the server, potentially even forever if that key is not loaded again.
m
Yeah, that's fair. If you are hitting this now, can you please create an issue and I'd be happy to work on it
r
I'm planning out my implementation so I haven't actually run into this yet, but I'm thinking through all the scenarios, and if I understand correctly I think I will run into this because in many cases the items I want to sync to the server are not read after they are published. I've created https://github.com/MobileNativeFoundation/Store/issues/677.
👍 1