Merge main into shared runtime foundations

Keep SyncGuard startup dependencies isolated in unload logging tests.
This commit is contained in:
vorotamoroz committed 2026-10-30 15:36:57 +00:00
commit bd05dde39c
83 files changed
+6313 -1507

No files matched your search

@@ -59,6 +59,7 @@ type ReplicateResultProcessorServices = Pick<
* database would be invalid.
*/
interface ReplicateResultProcessorContext {
readonly onVaultReflectionFailure?: () => void;
readonly currentSettings: () => ReplicateResultProcessorSettings;
readonly getKeyValueDB: () => LiveSyncBaseCore["kvDB"];
readonly getLocalDatabase: () => LiveSyncBaseCore["localDatabase"];
@@ -88,6 +89,7 @@ export class ReplicateResultProcessor {
Logger(e, LOG_LEVEL_VERBOSE);
}
private reportVaultReflectionFailure(entry: MetaEntry, cause?: unknown) {
this.context.onVaultReflectionFailure?.();
this.log(
`Live replication could not reflect ${this.getPath(entry)} from the local database to the Vault; this path remains eligible for a later Vault scan.`,
LOG_LEVEL_VERBOSE
@@ -379,6 +381,7 @@ export class ReplicateResultProcessor {
}
// Enqueue the change
this._queuedChanges.push(doc);
this.reportStatus();
this.updateProcessingActivity();
this.triggerTakeSnapshot();
this.triggerProcessQueue();
@@ -487,6 +490,9 @@ export class ReplicateResultProcessor {
} finally {
// Remove from processing queue
this._processingChanges = this._processingChanges.filter((e) => e !== change);
// Queue visibility must not wait for persisting a recovery snapshot. Consumers
// use this count to decide whether the reflected Vault is ready for interaction.
this.reportStatus();
try {
if (this._queuedChanges.length === 0 && this._processingChanges.length === 0) {
try {
@@ -511,6 +517,8 @@ export class ReplicateResultProcessor {
releaser = await this._semaphore.acquire();
await this._applyToDatabase(doc);
} catch (e) {
// An exception during application must not be mistaken for a fully reflected Vault.
this.context.onVaultReflectionFailure?.();
this.log(`Error while processing replication result`, LOG_LEVEL_NOTICE);
this.logError(e);
} finally {
@@ -544,6 +552,7 @@ export class ReplicateResultProcessor {
: await this.localDatabase.getDBEntryFromMeta({ ...dbDoc }, false, true);
if (!doc) {
// Failed to gather content
this.context.onVaultReflectionFailure?.();
this.log(`Failed to gather content of ${docNote}`, LOG_LEVEL_NOTICE);
return;
}
@@ -619,6 +628,7 @@ export class ReplicateResultProcessor {
// Note that this is not a common case.
return true;
} else {
this.context.onVaultReflectionFailure?.();
this.log(
`Failed to get existing document for ${path} (${shortenId(dbDoc._id)}, ${shortenRev(dbDoc._rev)}) `,
LOG_LEVEL_NOTICE