mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Spin on failed sqlite initialization
This commit is contained in:
parent
019b4f45e8
commit
06a647c473
@ -136,6 +136,7 @@ private final class MediaBoxKeepResourceContext {
|
|||||||
|
|
||||||
public final class MediaBox {
|
public final class MediaBox {
|
||||||
public let basePath: String
|
public let basePath: String
|
||||||
|
public let isMainProcess: Bool
|
||||||
|
|
||||||
private let statusQueue = Queue()
|
private let statusQueue = Queue()
|
||||||
private let concurrentQueue = Queue.concurrentDefaultQueue()
|
private let concurrentQueue = Queue.concurrentDefaultQueue()
|
||||||
@ -187,15 +188,16 @@ public final class MediaBox {
|
|||||||
let _ = try? FileManager.default.createDirectory(atPath: self.basePath + "/short-cache", withIntermediateDirectories: true, attributes: nil)
|
let _ = try? FileManager.default.createDirectory(atPath: self.basePath + "/short-cache", withIntermediateDirectories: true, attributes: nil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public init(basePath: String) {
|
public init(basePath: String, isMainProcess: Bool) {
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
|
self.isMainProcess = isMainProcess
|
||||||
|
|
||||||
self.storageBox = StorageBox(logger: StorageBox.Logger(impl: { string in
|
self.storageBox = StorageBox(logger: StorageBox.Logger(impl: { string in
|
||||||
postboxLog(string)
|
postboxLog(string)
|
||||||
}), basePath: basePath + "/storage")
|
}), basePath: basePath + "/storage", isMainProcess: isMainProcess)
|
||||||
self.cacheStorageBox = StorageBox(logger: StorageBox.Logger(impl: { string in
|
self.cacheStorageBox = StorageBox(logger: StorageBox.Logger(impl: { string in
|
||||||
postboxLog(string)
|
postboxLog(string)
|
||||||
}), basePath: basePath + "/cache-storage")
|
}), basePath: basePath + "/cache-storage", isMainProcess: isMainProcess)
|
||||||
|
|
||||||
self.timeBasedCleanup = TimeBasedCleanup(storageBox: self.storageBox, generalPaths: [
|
self.timeBasedCleanup = TimeBasedCleanup(storageBox: self.storageBox, generalPaths: [
|
||||||
self.basePath + "/cache",
|
self.basePath + "/cache",
|
||||||
|
@ -1368,7 +1368,7 @@ func debugRestoreState(basePath: String, name: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, encryptionParameters: ValueBoxEncryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32, isTemporary: Bool, isReadOnly: Bool, useCopy: Bool, useCaches: Bool, removeDatabaseOnError: Bool) -> Signal<PostboxResult, NoError> {
|
public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, encryptionParameters: ValueBoxEncryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32, isMainProcess: Bool, isTemporary: Bool, isReadOnly: Bool, useCopy: Bool, useCaches: Bool, removeDatabaseOnError: Bool) -> Signal<PostboxResult, NoError> {
|
||||||
let queue = Postbox.sharedQueue
|
let queue = Postbox.sharedQueue
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
queue.async {
|
queue.async {
|
||||||
@ -1496,7 +1496,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
|||||||
let endTime = CFAbsoluteTimeGetCurrent()
|
let endTime = CFAbsoluteTimeGetCurrent()
|
||||||
postboxLog("Postbox load took \((endTime - startTime) * 1000.0) ms")
|
postboxLog("Postbox load took \((endTime - startTime) * 1000.0) ms")
|
||||||
|
|
||||||
subscriber.putNext(.postbox(Postbox(queue: queue, basePath: basePath, seedConfiguration: seedConfiguration, valueBox: valueBox, timestampForAbsoluteTimeBasedOperations: timestampForAbsoluteTimeBasedOperations, isTemporary: isTemporary, tempDir: tempDir, useCaches: useCaches)))
|
subscriber.putNext(.postbox(Postbox(queue: queue, basePath: basePath, seedConfiguration: seedConfiguration, valueBox: valueBox, timestampForAbsoluteTimeBasedOperations: timestampForAbsoluteTimeBasedOperations, isMainProcess: isMainProcess, isTemporary: isTemporary, tempDir: tempDir, useCaches: useCaches)))
|
||||||
|
|
||||||
postboxLog("openPostbox, putCompletion")
|
postboxLog("openPostbox, putCompletion")
|
||||||
|
|
||||||
@ -4168,6 +4168,7 @@ public class Postbox {
|
|||||||
seedConfiguration: SeedConfiguration,
|
seedConfiguration: SeedConfiguration,
|
||||||
valueBox: SqliteValueBox,
|
valueBox: SqliteValueBox,
|
||||||
timestampForAbsoluteTimeBasedOperations: Int32,
|
timestampForAbsoluteTimeBasedOperations: Int32,
|
||||||
|
isMainProcess: Bool,
|
||||||
isTemporary: Bool,
|
isTemporary: Bool,
|
||||||
tempDir: TempBoxDirectory?,
|
tempDir: TempBoxDirectory?,
|
||||||
useCaches: Bool
|
useCaches: Bool
|
||||||
@ -4177,7 +4178,7 @@ public class Postbox {
|
|||||||
self.seedConfiguration = seedConfiguration
|
self.seedConfiguration = seedConfiguration
|
||||||
|
|
||||||
postboxLog("MediaBox path: \(basePath + "/media")")
|
postboxLog("MediaBox path: \(basePath + "/media")")
|
||||||
self.mediaBox = MediaBox(basePath: basePath + "/media")
|
self.mediaBox = MediaBox(basePath: basePath + "/media", isMainProcess: isMainProcess)
|
||||||
|
|
||||||
let isInTransaction = self.isInTransaction
|
let isInTransaction = self.isInTransaction
|
||||||
|
|
||||||
|
@ -163,20 +163,37 @@ public final class StorageBox {
|
|||||||
|
|
||||||
private var queuedInternalTransactions = Atomic<[() -> Void]>(value: [])
|
private var queuedInternalTransactions = Atomic<[() -> Void]>(value: [])
|
||||||
|
|
||||||
init(queue: Queue, logger: StorageBox.Logger, basePath: String) {
|
init(queue: Queue, logger: StorageBox.Logger, basePath: String, isMainProcess: Bool) {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
|
|
||||||
let databasePath = self.basePath + "/db"
|
let databasePath = self.basePath + "/db"
|
||||||
let _ = try? FileManager.default.createDirectory(atPath: databasePath, withIntermediateDirectories: true)
|
let _ = try? FileManager.default.createDirectory(atPath: databasePath, withIntermediateDirectories: true)
|
||||||
var valueBox = SqliteValueBox(basePath: databasePath, queue: queue, isTemporary: false, isReadOnly: false, useCaches: true, removeDatabaseOnError: true, encryptionParameters: nil, upgradeProgress: { _ in })
|
|
||||||
if valueBox == nil {
|
var valueBox: SqliteValueBox?
|
||||||
let _ = try? FileManager.default.removeItem(atPath: databasePath)
|
for i in 0 ..< 3 {
|
||||||
valueBox = SqliteValueBox(basePath: databasePath, queue: queue, isTemporary: false, isReadOnly: false, useCaches: true, removeDatabaseOnError: true, encryptionParameters: nil, upgradeProgress: { _ in })
|
if let valueBoxValue = SqliteValueBox(basePath: basePath + "/db", queue: queue, isTemporary: false, isReadOnly: false, useCaches: isMainProcess, removeDatabaseOnError: isMainProcess, encryptionParameters: nil, upgradeProgress: { _ in }) {
|
||||||
|
valueBox = valueBoxValue
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
postboxLog("Could not open value box at \(basePath + "/db") (try \(i))")
|
||||||
|
postboxLogSync()
|
||||||
|
|
||||||
|
Thread.sleep(forTimeInterval: 0.1 + 0.5 * Double(i))
|
||||||
}
|
}
|
||||||
guard let valueBox = valueBox else {
|
}
|
||||||
preconditionFailure("Could not open database")
|
|
||||||
|
if valueBox == nil, isMainProcess {
|
||||||
|
postboxLog("Removing value box at \(basePath + "/db")")
|
||||||
|
let _ = try? FileManager.default.removeItem(atPath: databasePath)
|
||||||
|
valueBox = SqliteValueBox(basePath: databasePath, queue: queue, isTemporary: false, isReadOnly: false, useCaches: isMainProcess, removeDatabaseOnError: isMainProcess, encryptionParameters: nil, upgradeProgress: { _ in })
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let valueBox else {
|
||||||
|
postboxLog("Giving up on opening value box at \(basePath + "/db")")
|
||||||
|
postboxLogSync()
|
||||||
|
preconditionFailure()
|
||||||
}
|
}
|
||||||
self.valueBox = valueBox
|
self.valueBox = valueBox
|
||||||
|
|
||||||
@ -1025,11 +1042,11 @@ public final class StorageBox {
|
|||||||
private let queue: Queue
|
private let queue: Queue
|
||||||
private let impl: QueueLocalObject<Impl>
|
private let impl: QueueLocalObject<Impl>
|
||||||
|
|
||||||
public init(logger: StorageBox.Logger, basePath: String) {
|
public init(logger: StorageBox.Logger, basePath: String, isMainProcess: Bool) {
|
||||||
let queue = StorageBox.sharedQueue
|
let queue = StorageBox.sharedQueue
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||||
return Impl(queue: queue, logger: logger, basePath: basePath)
|
return Impl(queue: queue, logger: logger, basePath: basePath, isMainProcess: isMainProcess)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ public func accountWithId(accountManager: AccountManager<TelegramAccountManagerT
|
|||||||
seedConfiguration: telegramPostboxSeedConfiguration,
|
seedConfiguration: telegramPostboxSeedConfiguration,
|
||||||
encryptionParameters: encryptionParameters,
|
encryptionParameters: encryptionParameters,
|
||||||
timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970),
|
timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970),
|
||||||
|
isMainProcess: !supplementary,
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
useCopy: false,
|
useCopy: false,
|
||||||
@ -1445,6 +1446,7 @@ public func standaloneStateManager(
|
|||||||
seedConfiguration: telegramPostboxSeedConfiguration,
|
seedConfiguration: telegramPostboxSeedConfiguration,
|
||||||
encryptionParameters: encryptionParameters,
|
encryptionParameters: encryptionParameters,
|
||||||
timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970),
|
timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970),
|
||||||
|
isMainProcess: false,
|
||||||
isTemporary: false,
|
isTemporary: false,
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
useCopy: false,
|
useCopy: false,
|
||||||
|
@ -92,11 +92,23 @@ final class AccountManagerImpl<Types: AccountManagerTypes> {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.guardValueBox = guardValueBox
|
self.guardValueBox = guardValueBox
|
||||||
guard let valueBox = SqliteValueBox(basePath: basePath + "/db", queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: nil, upgradeProgress: { _ in }) else {
|
|
||||||
postboxLog("Could not open value box at \(basePath + "/db")")
|
var valueBox: SqliteValueBox?
|
||||||
|
for i in 0 ..< 3 {
|
||||||
|
if let valueBoxValue = SqliteValueBox(basePath: basePath + "/db", queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: nil, upgradeProgress: { _ in }) {
|
||||||
|
valueBox = valueBoxValue
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
postboxLog("Could not open value box at \(basePath + "/db") (try \(i))")
|
||||||
|
postboxLogSync()
|
||||||
|
|
||||||
|
Thread.sleep(forTimeInterval: 0.1 + 0.5 * Double(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard let valueBox else {
|
||||||
|
postboxLog("Giving up on opening value box at \(basePath + "/db")")
|
||||||
postboxLogSync()
|
postboxLogSync()
|
||||||
preconditionFailure()
|
preconditionFailure()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
self.valueBox = valueBox
|
self.valueBox = valueBox
|
||||||
|
|
||||||
@ -537,7 +549,7 @@ public final class AccountManager<Types: AccountManagerTypes> {
|
|||||||
preconditionFailure()
|
preconditionFailure()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
self.mediaBox = MediaBox(basePath: basePath + "/media")
|
self.mediaBox = MediaBox(basePath: basePath + "/media", isMainProcess: removeDatabaseOnError)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func transaction<T>(ignoreDisabled: Bool = false, _ f: @escaping (AccountManagerModifier<Types>) -> T) -> Signal<T, NoError> {
|
public func transaction<T>(ignoreDisabled: Bool = false, _ f: @escaping (AccountManagerModifier<Types>) -> T) -> Signal<T, NoError> {
|
||||||
|
@ -172,7 +172,7 @@ public enum AccountTransactionError {
|
|||||||
|
|
||||||
public func accountTransaction<T>(rootPath: String, id: AccountRecordId, encryptionParameters: ValueBoxEncryptionParameters, isReadOnly: Bool, useCopy: Bool = false, useCaches: Bool = true, removeDatabaseOnError: Bool = true, transaction: @escaping (Postbox, Transaction) -> T) -> Signal<T, AccountTransactionError> {
|
public func accountTransaction<T>(rootPath: String, id: AccountRecordId, encryptionParameters: ValueBoxEncryptionParameters, isReadOnly: Bool, useCopy: Bool = false, useCaches: Bool = true, removeDatabaseOnError: Bool = true, transaction: @escaping (Postbox, Transaction) -> T) -> Signal<T, AccountTransactionError> {
|
||||||
let path = "\(rootPath)/\(accountRecordIdPathName(id))"
|
let path = "\(rootPath)/\(accountRecordIdPathName(id))"
|
||||||
let postbox = openPostbox(basePath: path + "/postbox", seedConfiguration: telegramPostboxSeedConfiguration, encryptionParameters: encryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970), isTemporary: true, isReadOnly: isReadOnly, useCopy: useCopy, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError)
|
let postbox = openPostbox(basePath: path + "/postbox", seedConfiguration: telegramPostboxSeedConfiguration, encryptionParameters: encryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970), isMainProcess: false, isTemporary: true, isReadOnly: isReadOnly, useCopy: useCopy, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError)
|
||||||
return postbox
|
return postbox
|
||||||
|> castError(AccountTransactionError.self)
|
|> castError(AccountTransactionError.self)
|
||||||
|> mapToSignal { value -> Signal<T, AccountTransactionError> in
|
|> mapToSignal { value -> Signal<T, AccountTransactionError> in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user