Changed the networking logic to suspend/resume rather than just cancel connections

pull/976/head
Morgan Pretty 1 month ago
parent b0eec5a4c2
commit 6cb9294143

@ -197,7 +197,7 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
// Stop all jobs except for message sending and when completed suspend the database
JobRunner.stopAndClearPendingJobs(exceptForVariant: .messageSend, using: dependencies) {
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
}

@ -147,6 +147,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
UNUserNotificationCenter.current().delegate = self
Storage.resumeDatabaseAccess()
LibSession.resumeNetworkAccess()
// Reset the 'startTime' (since it would be invalid from the last launch)
startTime = CACurrentMediaTime()
@ -211,7 +212,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// Stop all jobs except for message sending and when completed suspend the database
JobRunner.stopAndClearPendingJobs(exceptForVariant: .messageSend, using: dependencies) {
if !self.hasCallOngoing() {
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.info("[AppDelegate] completed network and database shutdowns.")
Log.flush()
@ -281,6 +282,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
Storage.resumeDatabaseAccess()
LibSession.resumeNetworkAccess()
// Background tasks only last for a certain amount of time (which can result in a crash and a
// prompt appearing for the user), we want to avoid this and need to make sure to suspend the
@ -298,7 +300,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
BackgroundPoller.isValid = false
if Singleton.hasAppContext && Singleton.appContext.isInBackground {
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
}
@ -325,7 +327,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
BackgroundPoller.isValid = false
if Singleton.hasAppContext && Singleton.appContext.isInBackground {
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
}

@ -114,7 +114,7 @@ public struct SessionApp {
public static func resetAppData(onReset: (() -> ())? = nil) {
LibSession.clearMemoryState()
LibSession.clearSnodeCache()
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.resetAllStorage()
ProfileManager.resetProfileStorage()
Attachment.resetAttachmentStorage()

@ -287,6 +287,7 @@ public enum PushRegistrationError: Error {
}
Storage.resumeDatabaseAccess()
LibSession.resumeNetworkAccess()
let maybeCall: SessionCall? = Storage.shared.write { db in
let messageInfo: CallMessage.MessageInfo = CallMessage.MessageInfo(

@ -51,6 +51,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
// Perform main setup
Storage.resumeDatabaseAccess()
LibSession.resumeNetworkAccess()
DispatchQueue.main.sync { self.setUpIfNecessary() { } }
// Handle the push notification
@ -349,7 +350,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
.map { NSNumber(value: $0) }
.defaulting(to: NSNumber(value: 0))
Log.info("Complete silently.")
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
@ -416,7 +417,7 @@ public final class NotificationServiceExtension: UNNotificationServiceExtension
private func handleFailure(for content: UNMutableNotificationContent, error: NotificationError) {
Log.error("Show generic failure message due to error: \(error).")
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()

@ -100,7 +100,7 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView
// When the thread picker disappears it means the user has left the screen (this will be called
// whether the user has sent the message or cancelled sending)
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
}
@ -229,6 +229,7 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView
ModalActivityIndicatorViewController.present(fromViewController: shareNavController!, canCancel: false, message: "vc_share_sending_message".localized()) { activityIndicator in
Storage.resumeDatabaseAccess()
LibSession.resumeNetworkAccess()
let swarmPublicKey: String = {
switch threadVariant {
@ -314,7 +315,7 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView
.receive(on: DispatchQueue.main)
.sinkUntilComplete(
receiveCompletion: { [weak self] result in
LibSession.closeNetworkConnections()
LibSession.suspendNetworkAccess()
Storage.suspendDatabaseAccess()
Log.flush()
activityIndicator.dismiss { }

@ -12,6 +12,7 @@ import SessionUtilitiesKit
public extension LibSession {
private static var networkCache: Atomic<UnsafeMutablePointer<network_object>?> = Atomic(nil)
private static var snodeCachePath: String { "\(OWSFileSystem.appSharedDataDirectoryPath())/snodeCache" }
private static var isSuspended: Atomic<Bool> = Atomic(false)
private static var lastPaths: Atomic<[[Snode]]> = Atomic([])
private static var lastNetworkStatus: Atomic<NetworkStatus> = Atomic(.unknown)
private static var pathsChangedCallbacks: Atomic<[UUID: ([[Snode]], UUID) -> ()]> = Atomic([:])
@ -114,12 +115,18 @@ public extension LibSession {
pathsChangedCallbacks.mutate { $0.removeValue(forKey: callbackId) }
}
static func closeNetworkConnections() {
static func suspendNetworkAccess() {
isSuspended.mutate { $0 = true }
guard let network: UnsafeMutablePointer<network_object> = networkCache.wrappedValue else { return }
network_close_connections(network)
}
static func resumeNetworkAccess() {
isSuspended.mutate { $0 = false }
}
static func clearSnodeCache() {
guard let network: UnsafeMutablePointer<network_object> = networkCache.wrappedValue else { return }
@ -329,6 +336,11 @@ public extension LibSession {
// MARK: - Internal Functions
private static func getOrCreateNetwork() -> AnyPublisher<UnsafeMutablePointer<network_object>?, Error> {
guard !isSuspended.wrappedValue else {
Log.warn("[LibSession] Attempted to access suspended network.")
return Fail(error: NetworkError.suspended).eraseToAnyPublisher()
}
guard networkCache.wrappedValue == nil else {
return Just(networkCache.wrappedValue)
.setFailureType(to: Error.self)

@ -15,6 +15,7 @@ public enum NetworkError: LocalizedError, Equatable {
case badRequest(error: String, rawData: Data?)
case requestFailed(error: String, rawData: Data?)
case timeout
case suspended
case unknown
public var errorDescription: String? {
@ -27,6 +28,7 @@ public enum NetworkError: LocalizedError, Equatable {
case .unauthorised: return "Unauthorised (Failed to verify the signature)."
case .badRequest(let error, _), .requestFailed(let error, _): return error
case .timeout: return "The request timed out."
case .suspended: return "Network requests are suspended."
case .unknown: return "An unknown error occurred."
}
}

Loading…
Cancel
Save