perf: move heavy work off main actor, throttle progress updates, add signposts
BackupEngine: - fetchAssets() runs in Task.detached — prevents 100-500ms UI freeze during PHFetchResult enumeration on large libraries - Manifest JSON decode + ManifestIndex Set construction run in Task.detached - pendingAssets filter runs in Task.detached — O(N) array filter off main thread - Progress updates throttled to 8 Hz via ProgressThrottle — eliminates the continuous SwiftUI full-tree redraws caused by per-byte upload callbacks - bytesSoFar captured by value in upload closure — avoids mutable var capture - reserveCapacity on manifestEntries array - os_signpost intervals on FetchAssets, NASConnect, ManifestLoad, BuildPendingQueue, UploadLoop, UploadFile for Instruments profiling BackupStatusService: - countSafe() marked nonisolated — runs in Task.detached off main actor, keeping touch/animation responsive during PHFetchResult batch enumeration - ManifestIndex JSON decode + Set construction run in Task.detached - Bootstrap ManifestIndex(nasListing:) construction off main actor - writeManifest JSON decode/encode/merge off main actor - os_signpost intervals on Reconcile, ManifestLoad, CountSafe Model types: - ManifestIndex, ManifestEntry, PhotoAsset, BackupFilter marked Sendable — safe to pass across task boundaries without warnings Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -4,7 +4,8 @@ import Photos
|
||||
// MARK: — ManifestIndex
|
||||
// Lightweight comparison structure — two Sets for O(1) lookups.
|
||||
// Built from BackupManifest and then the manifest is released.
|
||||
struct ManifestIndex {
|
||||
// Sendable: all stored properties are value types — safe to pass across task boundaries.
|
||||
struct ManifestIndex: Sendable {
|
||||
let localIdentifiers: Set<String> // PHAsset.localIdentifier (primary key)
|
||||
let lowercasedFilenames: Set<String> // filename fallback for legacy/bootstrap entries
|
||||
let totalCount: Int // non-hidden file count for NAS Archive stat
|
||||
@@ -50,7 +51,7 @@ struct ManifestIndex {
|
||||
|
||||
// MARK: — ManifestEntry
|
||||
|
||||
struct ManifestEntry: Codable {
|
||||
struct ManifestEntry: Codable, Sendable {
|
||||
let localIdentifier: String // PHAsset.localIdentifier — primary key
|
||||
let filename: String
|
||||
let creationDate: Date?
|
||||
|
||||
Reference in New Issue
Block a user