From 1ad3ff7161d91042d64fcf1181d1dc7e180ac39c Mon Sep 17 00:00:00 2001 From: gabriel20xx Date: Mon, 27 Oct 2025 18:31:21 +0100 Subject: [PATCH] fix: improve sync process by capturing a snapshot timestamp to avoid missing updates during in-flight sync --- .../app/data/repository/SyncRepository.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CollabTableAndroid/app/src/main/java/com/collabtable/app/data/repository/SyncRepository.kt b/CollabTableAndroid/app/src/main/java/com/collabtable/app/data/repository/SyncRepository.kt index c953a82..239cc7c 100644 --- a/CollabTableAndroid/app/src/main/java/com/collabtable/app/data/repository/SyncRepository.kt +++ b/CollabTableAndroid/app/src/main/java/com/collabtable/app/data/repository/SyncRepository.kt @@ -55,6 +55,10 @@ class SyncRepository(context: Context) { try { val lastServerTs = getLastServerSyncTs() val lastLocalTs = getLastLocalSyncTs() + // Capture a snapshot timestamp BEFORE reading local changes to avoid missing + // updates that happen during an in-flight sync. We'll advance the local watermark + // to this snapshot once the sync completes successfully. + val localSnapshotTs = System.currentTimeMillis() val isInitialSync = lastServerTs == 0L if (isInitialSync) { Logger.i("Sync", "[SYNC] Starting initial sync with server") @@ -62,9 +66,13 @@ class SyncRepository(context: Context) { // Gather local changes since last sync val localLists = database.listDao().getListsUpdatedSince(lastLocalTs) + .filter { it.updatedAt in (lastLocalTs + 1)..localSnapshotTs } val localFields = database.fieldDao().getFieldsUpdatedSince(lastLocalTs) + .filter { it.updatedAt in (lastLocalTs + 1)..localSnapshotTs } val localItems = database.itemDao().getItemsUpdatedSince(lastLocalTs) + .filter { it.updatedAt in (lastLocalTs + 1)..localSnapshotTs } val localValues = database.itemValueDao().getValuesUpdatedSince(lastLocalTs) + .filter { it.updatedAt in (lastLocalTs + 1)..localSnapshotTs } // Only log send when there are actual local changes val localTotal = localLists.size + localFields.size + localItems.size + localValues.size @@ -179,7 +187,9 @@ class SyncRepository(context: Context) { // Update watermarks: server ts from response, local ts from device clock now setLastServerSyncTs(syncResponse.serverTimestamp) - setLastLocalSyncTs(System.currentTimeMillis()) + // Advance local watermark to the snapshot taken before reading local changes. + // This avoids missing updates that occurred while the sync was in-flight. + setLastLocalSyncTs(localSnapshotTs) if (isInitialSync) { Logger.i("Sync", "[SYNC] Initial sync completed")