mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
DB optimizations
This commit is contained in:
@@ -182,9 +182,9 @@ public final class MediaBox {
|
||||
}
|
||||
|
||||
lazy var ensureDirectoryCreated: Void = {
|
||||
try! FileManager.default.createDirectory(atPath: self.basePath, withIntermediateDirectories: true, attributes: nil)
|
||||
try! FileManager.default.createDirectory(atPath: self.basePath + "/cache", withIntermediateDirectories: true, attributes: nil)
|
||||
try! FileManager.default.createDirectory(atPath: self.basePath + "/short-cache", withIntermediateDirectories: true, attributes: nil)
|
||||
let _ = try? FileManager.default.createDirectory(atPath: self.basePath, withIntermediateDirectories: true, attributes: nil)
|
||||
let _ = try? FileManager.default.createDirectory(atPath: self.basePath + "/cache", withIntermediateDirectories: true, attributes: nil)
|
||||
let _ = try? FileManager.default.createDirectory(atPath: self.basePath + "/short-cache", withIntermediateDirectories: true, attributes: nil)
|
||||
}()
|
||||
|
||||
public init(basePath: String) {
|
||||
@@ -677,7 +677,7 @@ public final class MediaBox {
|
||||
if let file = ManagedFile(queue: nil, path: paths.complete, mode: .read) {
|
||||
let clippedLowerBound = min(completeSize, max(0, range.lowerBound))
|
||||
let clippedUpperBound = min(completeSize, max(0, range.upperBound))
|
||||
if clippedLowerBound < clippedUpperBound {
|
||||
if clippedLowerBound < clippedUpperBound && (clippedUpperBound - clippedLowerBound) <= 64 * 1024 * 1024 {
|
||||
file.seek(position: clippedLowerBound)
|
||||
let data = file.readData(count: Int(clippedUpperBound - clippedLowerBound))
|
||||
subscriber.putNext((data, true))
|
||||
|
||||
@@ -2600,7 +2600,7 @@ final class PostboxImpl {
|
||||
}
|
||||
|
||||
let canBeginTransactionsValue = Atomic<Bool>(value: true)
|
||||
public func setCanBeginTransactions(_ value: Bool) {
|
||||
public func setCanBeginTransactions(_ value: Bool, afterTransactionIfRunning: @escaping () -> Void) {
|
||||
self.queue.async {
|
||||
let previous = self.canBeginTransactionsValue.swap(value)
|
||||
if previous != value && value {
|
||||
@@ -2609,6 +2609,7 @@ final class PostboxImpl {
|
||||
f()
|
||||
}
|
||||
}
|
||||
afterTransactionIfRunning()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3911,15 +3912,9 @@ public class Postbox {
|
||||
}
|
||||
}
|
||||
|
||||
public func setCanBeginTransactions(_ value: Bool) {
|
||||
#if DEBUG
|
||||
if !value {
|
||||
assert(!self.isInTransaction.with({ $0 }))
|
||||
}
|
||||
#endif
|
||||
|
||||
public func setCanBeginTransactions(_ value: Bool, afterTransactionIfRunning: @escaping () -> Void = {}) {
|
||||
self.impl.with { impl in
|
||||
impl.setCanBeginTransactions(value)
|
||||
impl.setCanBeginTransactions(value, afterTransactionIfRunning: afterTransactionIfRunning)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -565,7 +565,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let allIsOk = Atomic<Bool>(value: false)
|
||||
let removeDatabaseOnError = self.removeDatabaseOnError
|
||||
let databasePath = self.databasePath
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 5.0, execute: {
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 15.0, execute: {
|
||||
if allIsOk.with({ $0 }) == false {
|
||||
postboxLog("Timeout reached, discarding database")
|
||||
if removeDatabaseOnError {
|
||||
|
||||
@@ -305,6 +305,8 @@ public final class SharedWakeupManager {
|
||||
}
|
||||
}
|
||||
|
||||
var endTaskAfterTransactionsComplete: UIBackgroundTaskIdentifier?
|
||||
|
||||
if self.inForeground || self.hasActiveAudioSession || hasActiveCalls {
|
||||
if let (completion, timer) = self.currentExternalCompletion {
|
||||
self.currentExternalCompletion = nil
|
||||
@@ -389,12 +391,15 @@ public final class SharedWakeupManager {
|
||||
}
|
||||
} else if let (taskId, _, timer) = self.currentTask {
|
||||
self.currentTask = nil
|
||||
|
||||
timer.invalidate()
|
||||
self.endBackgroundTask(taskId)
|
||||
|
||||
endTaskAfterTransactionsComplete = taskId
|
||||
|
||||
self.isInBackgroundExtension = false
|
||||
}
|
||||
}
|
||||
self.updateAccounts(hasTasks: hasTasksForBackgroundExtension)
|
||||
self.updateAccounts(hasTasks: hasTasksForBackgroundExtension, endTaskAfterTransactionsComplete: endTaskAfterTransactionsComplete)
|
||||
|
||||
if hasPendingMessages {
|
||||
if self.keepIdleDisposable == nil {
|
||||
@@ -408,7 +413,7 @@ public final class SharedWakeupManager {
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAccounts(hasTasks: Bool) {
|
||||
private func updateAccounts(hasTasks: Bool, endTaskAfterTransactionsComplete: UIBackgroundTaskIdentifier?) {
|
||||
if self.inForeground || self.hasActiveAudioSession || self.isInBackgroundExtension || (hasTasks && self.currentExternalCompletion != nil) || self.activeExplicitExtensionTimer != nil {
|
||||
Logger.shared.log("Wakeup", "enableBeginTransactions: true (active)")
|
||||
|
||||
@@ -424,18 +429,55 @@ public final class SharedWakeupManager {
|
||||
account.shouldKeepOnlinePresence.set(.single(primary && self.inForeground))
|
||||
account.shouldKeepBackgroundDownloadConnections.set(.single(tasks.backgroundDownloads))
|
||||
}
|
||||
|
||||
if let endTaskAfterTransactionsComplete {
|
||||
self.endBackgroundTask(endTaskAfterTransactionsComplete)
|
||||
}
|
||||
} else {
|
||||
var enableBeginTransactions = false
|
||||
if self.allowBackgroundTimeExtensionDeadlineTimer != nil {
|
||||
enableBeginTransactions = true
|
||||
}
|
||||
Logger.shared.log("Wakeup", "enableBeginTransactions: \(enableBeginTransactions)")
|
||||
|
||||
final class CompletionObservationState {
|
||||
var isCompleted: Bool = false
|
||||
var remainingAccounts: [AccountRecordId]
|
||||
|
||||
init(remainingAccounts: [AccountRecordId]) {
|
||||
self.remainingAccounts = remainingAccounts
|
||||
}
|
||||
}
|
||||
let completionState = Atomic<CompletionObservationState>(value: CompletionObservationState(remainingAccounts: self.accountsAndTasks.map(\.0.id)))
|
||||
let checkCompletionState: (AccountRecordId?) -> Void = { id in
|
||||
Queue.mainQueue().async {
|
||||
var shouldComplete = false
|
||||
completionState.with { state in
|
||||
if let id {
|
||||
state.remainingAccounts.removeAll(where: { $0 == id })
|
||||
}
|
||||
if state.remainingAccounts.isEmpty && !state.isCompleted {
|
||||
state.isCompleted = true
|
||||
shouldComplete = true
|
||||
}
|
||||
}
|
||||
if shouldComplete, let endTaskAfterTransactionsComplete {
|
||||
self.endBackgroundTask(endTaskAfterTransactionsComplete)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (account, _, _) in self.accountsAndTasks {
|
||||
account.postbox.setCanBeginTransactions(enableBeginTransactions)
|
||||
let accountId = account.id
|
||||
account.postbox.setCanBeginTransactions(enableBeginTransactions, afterTransactionIfRunning: {
|
||||
checkCompletionState(accountId)
|
||||
})
|
||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||
account.shouldKeepOnlinePresence.set(.single(false))
|
||||
account.shouldKeepBackgroundDownloadConnections.set(.single(false))
|
||||
}
|
||||
|
||||
checkCompletionState(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user