persist method
Persist function called with the bath of documents that have changed (including been deleted) within the last throttle window
specified by the Persistor.persistenceThrottle
duration.
Implementation
@override
persist(docs) async {
// The updated persistence keys for documents are built into a local resolver
// passed to the worker. This has two main benefits:
// 1. It pre-computes the resolved persistence keys across the document updates, eliminating conflicts.
// Ex. If an update to users__1__friends__1 which resolves to persistence key "users" at resolver path "users"
// is followed a subsequent update to users__1 that changes the persistence key at resolver path "users" to "other_users",
// then the previous update to users__1__friends__1 would have an inaccurate persistence key.
// Pre-computing the local resolver ensures that all documents can lookup accurate persistence keys.
// were not pre-computed in this way, then there could be conflicts between the changes documents make
//
// 2. It de-duplicates persistence keys. If there are many documents that all roll up
// to a given key, then the key is only specified once in the local resolver rather than
// being duplicated and sent independently with each document.
final resolver = ValueStore<String>();
final List<FilePersistDocument> persistDocs = [];
final globalPersistorSettings = Loon.persistorSettings;
final defaultKey = switch (globalPersistorSettings) {
FilePersistorSettings(key: FilePersistorValueKey key) => key,
_ => FilePersistor.defaultKey,
};
resolver.write(ValueStore.root, defaultKey.value);
for (final doc in docs) {
bool encrypted = false;
final persistorSettings = doc.persistorSettings;
if (persistorSettings != null) {
final persistorDoc = persistorSettings.doc;
final docSettings = persistorSettings.settings;
encrypted =
docSettings is FilePersistorSettings && docSettings.encrypted;
switch (docSettings) {
case FilePersistorSettings(key: FilePersistorValueKey key):
String path;
/// A value key is stored at the parent path of the document unless it is a document
/// on the root collection via [Loon.doc], which should store keys under its own path.
if (persistorDoc.parent != Collection.root.path) {
path = persistorDoc.parent;
} else {
path = persistorDoc.path;
}
resolver.write(path, key.value);
break;
case FilePersistorSettings(key: FilePersistorBuilderKey keyBuilder):
final snap = persistorDoc.get();
final path = persistorDoc.path;
if (snap != null) {
resolver.write(path, (keyBuilder as dynamic)(snap));
}
break;
}
} else if (globalPersistorSettings is FilePersistorSettings) {
encrypted = globalPersistorSettings.encrypted;
switch (globalPersistorSettings) {
case FilePersistorSettings(key: FilePersistorBuilderKey keyBuilder):
final snap = doc.get();
final path = doc.path;
if (snap != null) {
resolver.write(path, (keyBuilder as dynamic)(snap));
}
break;
default:
break;
}
}
persistDocs.add(
FilePersistDocument(
path: doc.path,
data: doc.getSerialized(),
encrypted: encrypted,
),
);
}
await _sendMessage(
PersistMessageRequest(resolver: resolver, docs: persistDocs),
);
}