feat(backup): parallel uploads via connection pool + TaskGroup
Replace the sequential for-loop with withTaskGroup running N concurrent uploads. Each slot gets its own SMB/SFTP connection so uploads never block each other. Default concurrency is 3 (configurable via ConnectionStore.maxConcurrentUploads, capped at 6). - ConnectionStore: add maxConcurrentUploads (default 3, persisted) - BackupEngine: build pool of N connections at start, seed TaskGroup with one task per slot, recycle slots as tasks complete - Manifest checkpoints, pause, cancel, retry logic all preserved - SlotResult extracted to BackupEngine extension for Sendable conformance - Fix: remove undefined .trackScrollForTabBar() from BackupView Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -74,6 +74,11 @@ final class ConnectionStore: ObservableObject {
|
||||
didSet { UserDefaults.standard.set(notifyOnErrors, forKey: "notifyOnErrors") }
|
||||
}
|
||||
|
||||
// Parallel upload concurrency (1 = sequential, 3 = default, max 6)
|
||||
@Published var maxConcurrentUploads: Int {
|
||||
didSet { UserDefaults.standard.set(maxConcurrentUploads, forKey: "maxConcurrentUploads") }
|
||||
}
|
||||
|
||||
// Auto-backup via LAN trigger (trusted Wi-Fi join)
|
||||
@Published var autoBackupEnabled: Bool {
|
||||
didSet { UserDefaults.standard.set(autoBackupEnabled, forKey: "autoBackupEnabled") }
|
||||
@@ -113,6 +118,7 @@ final class ConnectionStore: ObservableObject {
|
||||
notifyOnStart = UserDefaults.standard.object(forKey: "notifyOnStart") as? Bool ?? false
|
||||
notifyOnComplete = UserDefaults.standard.object(forKey: "notifyOnComplete") as? Bool ?? true
|
||||
notifyOnErrors = UserDefaults.standard.object(forKey: "notifyOnErrors") as? Bool ?? true
|
||||
maxConcurrentUploads = UserDefaults.standard.object(forKey: "maxConcurrentUploads") as? Int ?? 3
|
||||
autoBackupEnabled = UserDefaults.standard.object(forKey: "autoBackupEnabled") as? Bool ?? true
|
||||
autoBackupOnOpen = UserDefaults.standard.object(forKey: "autoBackupOnOpen") as? Bool ?? false
|
||||
allowCellularBackup = UserDefaults.standard.object(forKey: "allowCellularBackup") as? Bool ?? false
|
||||
|
||||
Reference in New Issue
Block a user