diff --git a/Signal/AppLaunch/AppDelegate.swift b/Signal/AppLaunch/AppDelegate.swift index 1c17bb9398..f02a715a74 100644 --- a/Signal/AppLaunch/AppDelegate.swift +++ b/Signal/AppLaunch/AppDelegate.swift @@ -100,6 +100,12 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { // Ensure that all windows have the correct frame. WindowManager.shared.updateWindowFrames() + + AppReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { + self.incrementalMessageTSAttachmentMigrator?.runInMainAppBackgroundIfNeeded( + databaseStorage: self.databaseStorage + ) + } } private let flushQueue = DispatchQueue(label: "org.signal.flush", qos: .utility) diff --git a/Signal/src/IncrementalMessageTSAttachmentMigrator.swift b/Signal/src/IncrementalMessageTSAttachmentMigrator.swift index b87cd3964e..b5713cb85f 100644 --- a/Signal/src/IncrementalMessageTSAttachmentMigrator.swift +++ b/Signal/src/IncrementalMessageTSAttachmentMigrator.swift @@ -125,6 +125,11 @@ extension IncrementalMessageTSAttachmentMigrator { return case .started: // Don't _start_ in the main app, but continue making progress if we already started. + + if isRunningInMainApp.get() { + return + } + Logger.info("Continuing migration in main app") Task { await runInMainAppBackground() @@ -135,8 +140,19 @@ extension IncrementalMessageTSAttachmentMigrator { private func runInMainAppBackground() async { var batchCount = 0 var didFinish = false + isRunningInMainApp.set(true) + defer { + isRunningInMainApp.set(false) + } while !didFinish { do { + guard CurrentAppContext().isMainAppAndActive else { + // If the main app goes into the background, we shouldn't be + // grabbing the sql write lock. Stop. + Logger.info("Stopping when backgrounding app") + return + } + // Add a small delay between each batch to avoid locking the db write queue. try await Task.sleep(nanoseconds: 300 * NSEC_PER_MSEC) diff --git a/SignalServiceKit/Storage/Database/IncrementalMigrations/TSAttachment/IncrementalTSAttachmentMigrator.swift b/SignalServiceKit/Storage/Database/IncrementalMigrations/TSAttachment/IncrementalTSAttachmentMigrator.swift index 3522cd35dd..c83fac0f38 100644 --- a/SignalServiceKit/Storage/Database/IncrementalMigrations/TSAttachment/IncrementalTSAttachmentMigrator.swift +++ b/SignalServiceKit/Storage/Database/IncrementalMigrations/TSAttachment/IncrementalTSAttachmentMigrator.swift @@ -12,6 +12,8 @@ public protocol IncrementalMessageTSAttachmentMigrator { // Returns true if done. func runNextBatch() async throws -> Bool + + var isRunningInMainApp: AtomicBool { get } } public class IncrementalMessageTSAttachmentMigratorImpl: IncrementalMessageTSAttachmentMigrator { @@ -20,6 +22,8 @@ public class IncrementalMessageTSAttachmentMigratorImpl: IncrementalMessageTSAtt private let databaseStorage: SDSDatabaseStorage + public let isRunningInMainApp = AtomicBool(false, lock: .init()) + public init(databaseStorage: SDSDatabaseStorage) { self.databaseStorage = databaseStorage @@ -100,6 +104,8 @@ public class IncrementalMessageTSAttachmentMigratorImpl: IncrementalMessageTSAtt public class NoOpIncrementalMessageTSAttachmentMigrator: IncrementalMessageTSAttachmentMigrator { public init() {} + public let isRunningInMainApp = AtomicBool(false, lock: .init()) + public func runUntilFinished() async {} // Returns true if done. @@ -114,6 +120,8 @@ public class IncrementalMessageTSAttachmentMigratorMock: IncrementalMessageTSAtt public init() {} + public let isRunningInMainApp = AtomicBool(false, lock: .init()) + public func runUntilFinished() async {} // Returns true if done.