Source of Truth
Single authoritative local data source, ensuring data consistency and enabling offline support.
Purpose of the Source of Truth
The Source of Truth serves as the definitive local data source for your app. It provides:
- Data Consistency: Ensures that all parts of your application refer to a single, consistent data source.
- Offline Support: Enables your app to function without network connectivity by relying on locally persisted data.
- Synchronization: Bridges the gap between network data and local storage, ensuring that updates from the network are reflected in the local data source.
- Observability: Enables the Store to observe changes in the local data source and update consumers accordingly.
APIs
SourceOfTruth
SourceOfTruth has the following structure:
interface SourceOfTruth<Key : Any, Local : Any, Output : Any> {
fun reader(key: Key): Flow<Output?>
suspend fun write(key: Key, value: Local)
suspend fun delete(key: Key)
suspend fun deleteAll()
}- Parameter
Key- Type
Any- Required
- Required
- Description
The type representing the key used to identify the data item.
- Parameter
Local- Type
Any- Required
- Required
- Description
The type representing the local database model representation of the item being retrieved.
- Parameter
Output- Type
Any- Required
- Required
- Description
The type representing the domain data model representation of the item being retrieved.
reader
Reads data from the local data source for a given key. Returns a cold Flow emitting the domain data model associated with the key.
- Parameter
key- Type
Key- Required
- Required
- Description
The unique key identifying the data item to be retrieved.
write
Writes data to the local data source for a given key.
- Parameter
key- Type
Key- Required
- Required
- Description
The unique key identifying the data item.
- Parameter
value- Type
Local- Required
- Required
- Description
The data to be written, in the local data source format.
delete
Deletes a specific data item from the local data source.
- Parameter
key- Type
Key- Required
- Required
- Description
The unique key identifying the data item to be deleted.
deleteAll
Deletes all data items from the local data source.
Data Flow
Writing Data from Fetcher to Source of Truth
- Network Fetch1
Network Fetch
The Store fetches data from the network using the Fetcher.
kotlinval networkData = fetcher.fetch(key) - Write to Source of Truth2
Write to Source of Truth
The fetched data is written to the Source of Truth using the
writemethod.kotlinsourceOfTruth.write(key, networkData) - Notify Readers3
Notify Readers
Any active reader observing the key is notified of the new data.
Reading Data from Source of Truth
- Initiate Read1
Initiate Read
The consumer requests data from the Store.
kotlinval request = StoreReadRequest.cached(key, refresh) val flow = store.stream(request) - Source of Truth Reader2
Source of Truth Reader
The Store invokes the
readermethod of the Source of Truth.kotlinval localDataFlow = sourceOfTruth.reader(key) - Data Emission3
Data Emission
The Source of Truth emits data through the Flow returned by the
readermethod, which the Store passes to the consumer.
Handling Write and Read Synchronization
The Store uses a SourceOfTruthWithBarrier to synchronize read and write operations. This prevents race conditions and ensures data consistency.
- Barriers: Implemented using MutableStateFlow to block reads while a write is in progress.
- Versioning: Each read and write operation carries a version to coordinate updates accurately.
Best Practices
-
Use Observable Storage When Possible: Implement the
readermethod to return a Flow for real-time data updates. -
Handle Exceptions Gracefully: Ensure that exceptions are handled appropriately in both the
writeandreadermethods. -
Convert Between Data Types: Ensure proper conversion between network, local, and domain data types.