-
Notifications
You must be signed in to change notification settings - Fork 208
Store RFC: Improving Sync #697
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Matt Ramotar <[email protected]>
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #697 +/- ##
=======================================
Coverage 75.43% 75.43%
=======================================
Files 38 38
Lines 920 920
Branches 168 168
=======================================
Hits 694 694
Misses 142 142
Partials 84 84 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a look at this. I had a couple questions:
- Is Meeseeks one of the StoreX extensions coming in the future? There were a lot of references and I inferred that it would be one of them.
- Regarding partial failure handling: This is a new concept for me. Is the idea that some items may fail to update and we need to gracefully handle that case, whereas others may succeed so you can handle those as usual?
- I imagine a one case could look like this: You have a fetcher that's a stream to the server, new items are constantly coming in, based on any updates that may or may not have happened, the conflict resolution strategy will take care of how to handle the updates.
Thanks a lot for writing this up. The timeline at the bottom is promising too. I think this piece of the puzzle will help mobile developers solve a problem that many of them have but don't have the resources to create for themselves.
What would you like from us the consumers of Store?
@blakelee Hey Blake, thanks for taking a look.
|
docs/rfc/improving-sync.md
Outdated
|
||
The overarching goal of this RFC is to enhance Store5’s synchronization features without introducing breaking changes. In particular: | ||
|
||
1. **Synchronization Resilience**: Automated retries and background scheduling using the `Meeseeks` library (a KMP task scheduling library influenced by [WorkManager](https://developer.android.com/reference/androidx/work/WorkManager) and [BGTaskScheduler](https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler)). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn’t find the meeseeks library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhh, it’s described below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expanded on Meeseeks with links to the repo and docs 👍🏽
- **Reviewers**: _TBD_ | ||
- **Started**: February 22, 2025 | ||
|
||
## Introduction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was expecting to see a discussion of CRDTs
https://crdt.tech/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or perhaps Automerge which is a pretty rad implementation of CRDT ideas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requiring Store5 to store CRDTs would limit the types that users can leverage. It seems like the best place for them would be in the user's own conflict resolution wiring.
|
||
Store5 specifically introduced the `MutableStore` API to unify local and remote data synchronization. It provides mechanisms for create, update, and delete operations. However, we’ve identified critical gaps around resilience (automated retry, robust background sync) and deletion handling (both local and server-initiated removals). Along with these, we also need customizable conflict resolution strategies to better address real-world complexities. | ||
|
||
The overarching goal of this RFC is to enhance Store5’s synchronization features without introducing breaking changes. In particular: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implies there would be some changes proposed if we were interested in breaking changes, that aren't called out here. Is there anything else in the sync category, or something we would have proposed differently here, if that was on the table and we'd want to discuss those with a major version bump at some point in the future?
|
||
5. **Backward Compatibility** | ||
|
||
Not willing to break existing usage. Not all developers need advanced sync. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does advanced sync entail that we're intentionally leaving out?
Signed-off-by: Matt Ramotar <[email protected]>
|
||
The overarching goal of this RFC is to enhance Store5’s synchronization features without introducing breaking changes. In particular: | ||
|
||
1. **Synchronization Resilience**: Automated retries and background scheduling using the [Meeseeks](https://docs.meeseeks.mattramotar.dev/) library (a KMP task scheduling library influenced by [WorkManager](https://developer.android.com/reference/androidx/work/WorkManager) and [BGTaskScheduler](https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler)). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should also be a way to trigger it manually. On iOS in aprticular BGTaskScheduler
is not very configurable -- it is basically up to the OS when to call the task, and iOS provides very few if any guarantees on timing.
The system decides the best time to launch your background task, and provides your app up to 30 seconds of background runtime.
Alternative strategies include things like waking the app with a background push and triggering sync from there, but this requires the manual API.
- **Reviewers**: _TBD_ | ||
- **Started**: February 22, 2025 | ||
|
||
## Introduction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requiring Store5 to store CRDTs would limit the types that users can leverage. It seems like the best place for them would be in the user's own conflict resolution wiring.
|
||
We have the building blocks for robust sync ([MutableStore](https://store.mobilenativefoundation.org/docs/concepts/store5/mutable-store), [Bookkeeper](https://store.mobilenativefoundation.org/docs/concepts/store5/bookkeeper), [Updater](https://store.mobilenativefoundation.org/docs/concepts/store5/updater), [SourceOfTruth](https://store.mobilenativefoundation.org/docs/concepts/store5/source-of-truth)). But we need to tighten up deletion support, add background sync scheduling, and clarify conflict resolution flows. | ||
|
||
## Considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a consideration here for synchronization failure handling? Say an item is added to the SoT. When this item syncs to the server, there are two possibilities: 1) the item is invalid in some way, and rejected by the server (think 400 Bad Request), or 2) the item fails to sync due to some temporary problem e.g. network error, backend component down, etc. (think 502 Bad Gateway).
This also implies some kind of maximum retries counter -- sometimes the server does not correctly identify a bad request and instead returns a 500 Server Error. But the error is due to a problem in the request, so we can't keep retrying it forever.
These failed items should be stored in a way that the problem can optionally be surfaced to a user for correction, and updating the item in the local SoT.
I wrote this in #677 :
Lastly, some values may never sync to the server because it is malformed or violates server preconditions in some way. Part of the API should allow inspecting the failures for items that have failed to sync and invalidating them i.e. clearing or setting some relevant state in bookkeeper and moving them to some kind of "failed" status in the source of truth.
|
||
We have the building blocks for robust sync ([MutableStore](https://store.mobilenativefoundation.org/docs/concepts/store5/mutable-store), [Bookkeeper](https://store.mobilenativefoundation.org/docs/concepts/store5/bookkeeper), [Updater](https://store.mobilenativefoundation.org/docs/concepts/store5/updater), [SourceOfTruth](https://store.mobilenativefoundation.org/docs/concepts/store5/source-of-truth)). But we need to tighten up deletion support, add background sync scheduling, and clarify conflict resolution flows. | ||
|
||
## Considerations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another consideration is the ability to retrieve the sync state of items. I wrote this in #677 :
Related to this, I would like a nice API to retrieve information about failed syncs. This could be used to display information to the user like "5 items have not yet synced to the server"
I'm not sure if Bookkeeper already provides this capability.
See: #677, #685