From c415dceb22451763490f2ea6a855b9e76f5eb1f5 Mon Sep 17 00:00:00 2001 From: Amir Khodak Date: Sat, 6 Jun 2026 17:44:59 +0000 Subject: [PATCH] v1.0.60: skip remote directories in sync + reduce concurrency to 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Filter out isDirectory entries from remoteFiles so remote folders are never treated as files to sync (fixes phantom-directory 'Partial ✗5' status) - Lower Semaphore from 4 → 2 to reduce concurrent SFTP sessions and avoid hitting server session limits --- app/src/main/kotlin/com/syncflow/domain/sync/SyncEngine.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/syncflow/domain/sync/SyncEngine.kt b/app/src/main/kotlin/com/syncflow/domain/sync/SyncEngine.kt index 0a5b7c6..5379bb6 100644 --- a/app/src/main/kotlin/com/syncflow/domain/sync/SyncEngine.kt +++ b/app/src/main/kotlin/com/syncflow/domain/sync/SyncEngine.kt @@ -77,6 +77,7 @@ class SyncEngine @Inject constructor( val accessor = makeAccessor(pair.localPath) var knownStates = fileStateDao.getForPair(pair.id).associateBy { it.relativePath } val remoteFiles = provider.listFiles(pair.remotePath).getOrThrow() + .filter { !it.isDirectory } // skip remote directories — they are not sync targets .associateBy { it.path.removePrefix(pair.remotePath).trimStart('/') } val localFiles = accessor.walkFiles(pair) @@ -93,7 +94,7 @@ class SyncEngine @Inject constructor( val allPaths = (localFiles.keys + remoteFiles.keys + knownStates.keys).toSet() val hasPriorSyncState = knownStates.isNotEmpty() - val semaphore = Semaphore(4) + val semaphore = Semaphore(2) // limit concurrency to be gentle on the server val uploadedAtomic = AtomicInteger(0) val downloadedAtomic = AtomicInteger(0) val deletedAtomic = AtomicInteger(0)