Bookkeeper
Designed to track local data changes that haven’t been successfully synchronized with the remote data source. It plays a crucial role in conflict resolution, especially in applications that support offline operations or have intermittent network connectivity.
Relevant Context
Check out Google’s Offline First guide for more information on conflict resolution strategies.
Conflict resolution is critical when your app makes local changes while offline or when there are discrepancies between the client and server data. The Bookkeeper helps by:
- Versioning: Recording timestamps of failed syncs allows you to determine when changes occurred, which is essential for resolving conflicts.
- Strategies: Depending on your application’s needs, you might implement different conflict resolution strategies. A common approach in mobile apps is “last write wins,” where the most recent change overwrites previous ones.
Purpose of the Bookkeeper
- Tracking Failed Synchronizations: The Bookkeeper records instances when local updates fail to sync with the remote source.
- Conflict Resolution: By keeping a record of failed syncs, the Bookkeeper enables the Store to identify and resolve conflicts between local and remote data upon the next synchronization attempt.
- Data Consistency: Helps maintain consistency between the client’s local data and the server’s data by ensuring that unsynced changes are not forgotten and are eventually synchronized.
APIs
Bookkeeper
Bookkeeper has the following structure:
The type representing the key used to identify the data item.
Returns the timestamp of the last failed sync attempt for the given key.
Records a failed sync attempt with the provided timestamp.
Clears the record of failed syncs for the given key.
Clears all records of failed syncs.
Data Flow
Local Changes Made
The application makes a local change that needs to be synced with the remote source.
Sync Attempt
The Store attempts to update the remote source using the Updater.
Write Response Handling
- On Success: If the sync succeeds, the Bookkeeper clears any records of failed syncs for that key.
- On Failure: If the sync fails, the Bookkeeper records the failure along with a timestamp.
Conflict Resolution on Read
-
Before serving data, the Store checks with the Bookkeeper to see if there are any unsynced local changes.
-
If there are failed syncs, the Store attempts to resolve them before returning data.
Implementing a Bookkeeper
You can create a Bookkeeper using the Bookkeeper.by
factory method:
Example
From the Trails app:
Best Practices
- Persistent Storage: Use persistent storage (e.g., a local database) for the Bookkeeper to ensure that failed sync records are not lost between app sessions.
- Error Handling: Ensure that exceptions are properly caught and handled when performing sync operations.