From aefdbeb7bcc2a4a798f280163831d3511dae0cd7 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 13 Nov 2019 13:12:25 +1100 Subject: [PATCH] Fix threading --- .../src/Loki/API/LokiAPI+SwarmAPI.swift | 8 +++---- SignalServiceKit/src/Loki/API/LokiAPI.swift | 12 +++++----- .../src/Loki/API/LokiDotNetAPI.swift | 10 ++++---- .../src/Loki/API/LokiLongPoller.swift | 8 +++---- .../src/Loki/API/LokiMessage.swift | 2 +- .../src/Loki/API/LokiStorageAPI.swift | 8 +++---- .../API/Public Chat/LokiPublicChatAPI.swift | 24 +++++++++---------- .../Public Chat/LokiPublicChatManager.swift | 2 +- .../Public Chat/LokiPublicChatPoller.swift | 4 ++-- .../src/Loki/Utilities/Promise+Retrying.swift | 2 +- .../src/Messages/OWSMessageManager.m | 4 +++- .../src/Network/API/NetworkManager.swift | 7 +++++- 12 files changed, 49 insertions(+), 42 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index b13aee3f0..da761171a 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -63,7 +63,7 @@ public extension LokiAPI { ] ]) print("[Loki] Invoking get_n_service_nodes on \(target).") - return TSNetworkManager.shared().makePromise(request: request).map { intermediate in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { intermediate in let rawResponse = intermediate.responseObject guard let json = rawResponse as? JSON, let intermediate = json["result"] as? JSON, let rawTargets = intermediate["service_node_states"] as? [JSON] else { throw "Failed to update random snode pool from: \(rawResponse)." } randomSnodePool = try Set(rawTargets.flatMap { rawTarget in @@ -74,7 +74,7 @@ public extension LokiAPI { return LokiAPITarget(address: "https://\(address)", port: UInt16(port)) }) return randomSnodePool.randomElement()! - }.recover { error -> Promise in + }.recover(on: DispatchQueue.global()) { error -> Promise in print("[Loki] Failed to contact seed node at: \(target).") Analytics.shared.track("Seed Node Failed") throw error @@ -91,7 +91,7 @@ public extension LokiAPI { return Promise<[LokiAPITarget]> { $0.fulfill(cachedSwarm) } } else { let parameters: [String:Any] = [ "pubKey" : hexEncodedPublicKey ] - return getRandomSnode().then { invoke(.getSwarm, on: $0, associatedWith: hexEncodedPublicKey, parameters: parameters) }.map { parseTargets(from: $0) }.get { swarmCache[hexEncodedPublicKey] = $0 } + return getRandomSnode().then(on: DispatchQueue.global()) { invoke(.getSwarm, on: $0, associatedWith: hexEncodedPublicKey, parameters: parameters) }.map { parseTargets(from: $0) }.get { swarmCache[hexEncodedPublicKey] = $0 } } } @@ -121,7 +121,7 @@ public extension LokiAPI { internal extension Promise { internal func handlingSwarmSpecificErrorsIfNeeded(for target: LokiAPITarget, associatedWith hexEncodedPublicKey: String) -> Promise { - return recover { error -> Promise in + return recover(on: DispatchQueue.global()) { error -> Promise in if let error = error as? NetworkManagerError { switch error.statusCode { case 0, 400, 500, 503: diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index 9f64fa39c..67dcff4c0 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -87,7 +87,7 @@ public final class LokiAPI : NSObject { let headers = request.allHTTPHeaderFields ?? [:] let headersDescription = headers.isEmpty ? "no custom headers specified" : headers.prettifiedDescription print("[Loki] Invoking \(method.rawValue) on \(target) with \(parameters.prettifiedDescription) (\(headersDescription)).") - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject } + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject } .handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey).recoveringNetworkErrorsIfNeeded() } @@ -130,10 +130,10 @@ public final class LokiAPI : NSObject { if timeSinceLastUpdate > deviceLinkUpdateInterval { storage.dbReadConnection.read { transaction in let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) ?? hexEncodedPublicKey - LokiStorageAPI.getDeviceLinks(associatedWith: masterHexEncodedPublicKey).done { _ in + LokiStorageAPI.getDeviceLinks(associatedWith: masterHexEncodedPublicKey).done(on: DispatchQueue.global()) { _ in getDestinations() lastDeviceLinkUpdate[hexEncodedPublicKey] = Date() - }.catch { error in + }.catch(on: DispatchQueue.global()) { error in if case LokiDotNetAPI.Error.parsingFailed = error { // Don't immediately re-fetch in case of failure due to a parsing error lastDeviceLinkUpdate[hexEncodedPublicKey] = Date() @@ -157,7 +157,7 @@ public final class LokiAPI : NSObject { return invoke(.sendMessage, on: target, associatedWith: destination, parameters: parameters) } func sendLokiMessageUsingSwarmAPI() -> Promise> { - return lokiMessage.calculatePoW().then { lokiMessageWithPoW in + return lokiMessage.calculatePoW().then(on: DispatchQueue.global()) { lokiMessageWithPoW in return getTargetSnodes(for: destination).map { swarm in return Set(swarm.map { target in sendLokiMessage(lokiMessageWithPoW, to: target).map { rawResponse in @@ -179,7 +179,7 @@ public final class LokiAPI : NSObject { return Promise.value([ target ]).mapValues { sendLokiMessage(lokiMessage, to: $0) }.map { Set($0) }.retryingIfNeeded(maxRetryCount: maxRetryCount).get { _ in LokiP2PAPI.markOnline(destination) onP2PSuccess() - }.recover { error -> Promise> in + }.recover(on: DispatchQueue.global()) { error -> Promise> in LokiP2PAPI.markOffline(destination) if lokiMessage.isPing { print("[Loki] Failed to ping \(destination); marking contact as offline.") @@ -368,7 +368,7 @@ public final class LokiAPI : NSObject { private extension Promise { fileprivate func recoveringNetworkErrorsIfNeeded() -> Promise { - return recover() { error -> Promise in + return recover(on: DispatchQueue.global()) { error -> Promise in switch error { case NetworkManagerError.taskError(_, let underlyingError): throw underlyingError default: throw error diff --git a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift index 931deb1f5..3e8c23337 100644 --- a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift @@ -40,7 +40,7 @@ public class LokiDotNetAPI : NSObject { public static func uploadAttachment(_ attachment: TSAttachmentStream, with attachmentID: String, to server: String) -> Promise { let isEncryptionRequired = (server == LokiStorageAPI.server) return Promise() { seal in - getAuthToken(for: server).done { token in + getAuthToken(for: server).done(on: DispatchQueue.global()) { token in let data: Data guard let unencryptedAttachmentData = try? attachment.readDataFromFile() else { print("[Loki] Couldn't read attachment data from disk.") @@ -104,7 +104,7 @@ public class LokiDotNetAPI : NSObject { return seal.fulfill(()) }) task.resume() - }.catch { error in + }.catch(on: DispatchQueue.global()) { error in print("[Loki] Couldn't upload attachment.") seal.reject(error) } @@ -116,7 +116,7 @@ public class LokiDotNetAPI : NSObject { if let token = getAuthTokenFromDatabase(for: server) { return Promise.value(token) } else { - return requestNewAuthToken(for: server).then { submitAuthToken($0, for: server) }.map { token -> String in + return requestNewAuthToken(for: server).then(on: DispatchQueue.global()) { submitAuthToken($0, for: server) }.map { token -> String in setAuthToken(for: server, to: token) return token } @@ -129,7 +129,7 @@ public class LokiDotNetAPI : NSObject { let queryParameters = "pubKey=\(userHexEncodedPublicKey)" let url = URL(string: "\(server)/loki/v1/get_challenge?\(queryParameters)")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let base64EncodedChallenge = json["cipherText64"] as? String, let base64EncodedServerPublicKey = json["serverPubKey64"] as? String, let challenge = Data(base64Encoded: base64EncodedChallenge), var serverPublicKey = Data(base64Encoded: base64EncodedServerPublicKey) else { throw Error.parsingFailed @@ -153,7 +153,7 @@ public class LokiDotNetAPI : NSObject { let url = URL(string: "\(server)/loki/v1/submit_challenge")! let parameters = [ "pubKey" : userHexEncodedPublicKey, "token" : token ] let request = TSRequest(url: url, method: "POST", parameters: parameters) - return TSNetworkManager.shared().makePromise(request: request).map { _ in token } + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { _ in token } } // MARK: Attachments (Public Obj-C API) diff --git a/SignalServiceKit/src/Loki/API/LokiLongPoller.swift b/SignalServiceKit/src/Loki/API/LokiLongPoller.swift index 1acb6f7db..e5b1d807f 100644 --- a/SignalServiceKit/src/Loki/API/LokiLongPoller.swift +++ b/SignalServiceKit/src/Loki/API/LokiLongPoller.swift @@ -42,7 +42,7 @@ public final class LokiLongPoller : NSObject { // MARK: Private API private func openConnections() { guard !hasStopped else { return } - LokiAPI.getSwarm(for: userHexEncodedPublicKey).then { [weak self] _ -> Guarantee<[Result]> in + LokiAPI.getSwarm(for: userHexEncodedPublicKey).then(on: DispatchQueue.global()) { [weak self] _ -> Guarantee<[Result]> in guard let strongSelf = self else { return Guarantee.value([Result]()) } strongSelf.usedSnodes.removeAll() let connections: [Promise] = (0..) -> Promise { - return LokiAPI.getRawMessages(from: target, usingLongPolling: true).then { [weak self] rawResponse -> Promise in + return LokiAPI.getRawMessages(from: target, usingLongPolling: true).then(on: DispatchQueue.global()) { [weak self] rawResponse -> Promise in guard let strongSelf = self, !strongSelf.hasStopped else { return Promise.value(()) } let messages = LokiAPI.parseRawMessagesResponse(rawResponse, from: target) strongSelf.onMessagesReceived(messages) diff --git a/SignalServiceKit/src/Loki/API/LokiMessage.swift b/SignalServiceKit/src/Loki/API/LokiMessage.swift index 3ee57dbe0..637ffb621 100644 --- a/SignalServiceKit/src/Loki/API/LokiMessage.swift +++ b/SignalServiceKit/src/Loki/API/LokiMessage.swift @@ -49,7 +49,7 @@ public struct LokiMessage { /// - Returns: The promise of a new message with its `timestamp` and `nonce` set. public func calculatePoW() -> Promise { return Promise { seal in - DispatchQueue.global(qos: .default).async { + DispatchQueue.global().async { let now = NSDate.ows_millisecondTimeStamp() let dataAsString = self.data as! String // Safe because of how from(signalMessage:with:) is implemented if let nonce = ProofOfWork.calculate(data: dataAsString, pubKey: self.destination, timestamp: now, ttl: self.ttl) { diff --git a/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift b/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift index 002913e69..52bdf7a65 100644 --- a/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift @@ -19,11 +19,11 @@ public final class LokiStorageAPI : LokiDotNetAPI { /// server and stores and returns the valid ones. public static func getDeviceLinks(associatedWith hexEncodedPublicKey: String) -> Promise> { print("[Loki] Getting device links for: \(hexEncodedPublicKey).") - return getAuthToken(for: server).then { token -> Promise> in + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise> in let queryParameters = "include_user_annotations=1" let url = URL(string: "\(server)/users/@\(hexEncodedPublicKey)?\(queryParameters)")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse -> Set in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse -> Set in guard let json = rawResponse as? JSON, let data = json["data"] as? JSON, let annotations = data["annotations"] as? [JSON] else { print("[Loki] Couldn't parse device links for user: \(hexEncodedPublicKey) from: \(rawResponse).") @@ -74,7 +74,7 @@ public final class LokiStorageAPI : LokiDotNetAPI { public static func setDeviceLinks(_ deviceLinks: Set) -> Promise { print("[Loki] Updating device links.") - return getAuthToken(for: server).then { token -> Promise in + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise in let isMaster = deviceLinks.contains { $0.master.hexEncodedPublicKey == userHexEncodedPublicKey } let deviceLinksAsJSON = deviceLinks.map { $0.toJSON() } let value = !deviceLinksAsJSON.isEmpty ? [ "isPrimary" : isMaster ? 1 : 0, "authorisations" : deviceLinksAsJSON ] : nil @@ -83,7 +83,7 @@ public final class LokiStorageAPI : LokiDotNetAPI { let url = URL(string: "\(server)/users/me")! let request = TSRequest(url: url, method: "PATCH", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] - return TSNetworkManager.shared().makePromise(request: request).map { _ in }.recover { error in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { _ in }.recover(on: DispatchQueue.global()) { error in print("Couldn't update device links due to error: \(error).") throw error } diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift index 7566c139f..8359925b0 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift @@ -83,7 +83,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } let url = URL(string: "\(server)/channels/\(channel)/messages?\(queryParameters)")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let rawMessages = json["data"] as? [JSON] else { print("[Loki] Couldn't parse messages for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed @@ -136,14 +136,14 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { public static func sendMessage(_ message: LokiPublicChatMessage, to channel: UInt64, on server: String) -> Promise { guard let signedMessage = message.sign(with: userKeyPair.privateKey) else { return Promise(error: Error.signingFailed) } - return getAuthToken(for: server).then { token -> Promise in + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise in print("[Loki] Sending message to public chat channel with ID: \(channel) on server: \(server).") let url = URL(string: "\(server)/channels/\(channel)/messages")! let parameters = signedMessage.toJSON() let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] let displayName = userDisplayName - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in // ISO8601DateFormatter doesn't support milliseconds before iOS 11 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" @@ -155,7 +155,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { let timestamp = UInt64(date.timeIntervalSince1970) * 1000 return LokiPublicChatMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: signedMessage.quote, attachments: signedMessage.attachments, signature: signedMessage.signature) } - }.recover { error -> Promise in + }.recover(on: DispatchQueue.global()) { error -> Promise in if let error = error as? NetworkManagerError, error.statusCode == 401 { print("[Loki] Group chat auth token for: \(server) expired; dropping it.") storage.dbReadWriteConnection.removeObject(forKey: server, inCollection: authTokenCollection) @@ -164,7 +164,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { }.retryingIfNeeded(maxRetryCount: maxRetryCount).map { message in Analytics.shared.track("Group Message Sent") return message - }.recover { error -> Promise in + }.recover(on: DispatchQueue.global()) { error -> Promise in Analytics.shared.track("Failed to Send Group Message") throw error } @@ -180,7 +180,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } let url = URL(string: "\(server)/loki/v1/channel/\(channel)/deletes?\(queryParameters)")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let deletions = json["data"] as? [JSON] else { print("[Loki] Couldn't parse deleted messages for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed @@ -198,14 +198,14 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } public static func deleteMessage(with messageID: UInt, for channel: UInt64, on server: String, isSentByUser: Bool) -> Promise { - return getAuthToken(for: server).then { token -> Promise in + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise in let isModerationRequest = !isSentByUser print("[Loki] Deleting message with ID: \(messageID) for public chat channel with ID: \(channel) on server: \(server) (isModerationRequest = \(isModerationRequest)).") let urlAsString = isSentByUser ? "\(server)/channels/\(channel)/messages/\(messageID)" : "\(server)/loki/v1/moderation/message/\(messageID)" let url = URL(string: urlAsString)! let request = TSRequest(url: url, method: "DELETE", parameters: [:]) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] - return TSNetworkManager.shared().makePromise(request: request).done { result -> Void in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).done(on: DispatchQueue.global()) { result -> Void in print("[Loki] Deleted message with ID: \(messageID) on server: \(server).") }.retryingIfNeeded(maxRetryCount: maxRetryCount) } @@ -214,7 +214,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { public static func getModerators(for channel: UInt64, on server: String) -> Promise> { let url = URL(string: "\(server)/loki/v1/channel/\(channel)/get_moderators")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let moderators = json["moderators"] as? [String] else { print("[Loki] Couldn't parse moderators for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed @@ -236,12 +236,12 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { public static func setDisplayName(to newDisplayName: String?, on server: String) -> Promise { print("[Loki] Updating display name on server: \(server).") - return getAuthToken(for: server).then { token -> Promise in + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise in let parameters: JSON = [ "name" : (newDisplayName ?? "") ] let url = URL(string: "\(server)/users/me")! let request = TSRequest(url: url, method: "PATCH", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] - return TSNetworkManager.shared().makePromise(request: request).map { _ in }.recover { error in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { _ in }.recover(on: DispatchQueue.global()) { error in print("Couldn't update display name due to error: \(error).") throw error } @@ -251,7 +251,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { public static func getInfo(for channel: UInt64, on server: String) -> Promise { let url = URL(string: "\(server)/channels/\(channel)?include_annotations=1")! let request = TSRequest(url: url) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let data = json["data"] as? JSON, let annotations = data["annotations"] as? [JSON], diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift index ef260a994..358544604 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift @@ -54,7 +54,7 @@ public final class LokiPublicChatManager : NSObject { return Promise(error: Error.chatCreationFailed) } } - return LokiPublicChatAPI.getAuthToken(for: server).then { token in + return LokiPublicChatAPI.getAuthToken(for: server).then(on: DispatchQueue.global()) { token in return LokiPublicChatAPI.getInfo(for: channel, on: server) }.map { channelInfo -> LokiPublicChat in guard let chat = self.addChat(server: server, channel: channel, name: channelInfo.displayName) else { throw Error.chatCreationFailed } diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift index 7dcaeb38f..807614ada 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift @@ -155,7 +155,7 @@ public final class LokiPublicChatPoller : NSObject { } } // Poll - let _ = LokiPublicChatAPI.getMessages(for: publicChat.channel, on: publicChat.server).done(on: .main) { messages in + let _ = LokiPublicChatAPI.getMessages(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { messages in messages.forEach { message in if message.hexEncodedPublicKey != userHexEncodedPublicKey { processIncomingMessage(message) @@ -168,7 +168,7 @@ public final class LokiPublicChatPoller : NSObject { private func pollForDeletedMessages() { let publicChat = self.publicChat - let _ = LokiPublicChatAPI.getDeletedMessageServerIDs(for: publicChat.channel, on: publicChat.server).done { deletedMessageServerIDs in + let _ = LokiPublicChatAPI.getDeletedMessageServerIDs(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { deletedMessageServerIDs in let storage = OWSPrimaryStorage.shared() storage.dbReadWriteConnection.readWrite { transaction in let deletedMessageIDs = deletedMessageServerIDs.compactMap { storage.getIDForMessage(withServerID: UInt($0), in: transaction) } diff --git a/SignalServiceKit/src/Loki/Utilities/Promise+Retrying.swift b/SignalServiceKit/src/Loki/Utilities/Promise+Retrying.swift index eb340081e..b23381141 100644 --- a/SignalServiceKit/src/Loki/Utilities/Promise+Retrying.swift +++ b/SignalServiceKit/src/Loki/Utilities/Promise+Retrying.swift @@ -5,7 +5,7 @@ internal extension Promise { internal func retryingIfNeeded(maxRetryCount: UInt) -> Promise { var retryCount = 0 func retryIfNeeded() -> Promise { - return recover { error -> Promise in + return recover(on: DispatchQueue.global()) { error -> Promise in guard retryCount != maxRetryCount else { throw error } retryCount += 1 return retryIfNeeded() diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index a6e6cbecf..cc2f2a936 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -1447,7 +1447,9 @@ NS_ASSUME_NONNULL_BEGIN } // Loki: Cache the user hex encoded public key (for mentions) - [LKAPI populateUserHexEncodedPublicKeyCacheIfNeededFor:oldGroupThread.uniqueId in:transaction]; + dispatch_sync(dispatch_get_main_queue(), ^{ + [LKAPI populateUserHexEncodedPublicKeyCacheIfNeededFor:oldGroupThread.uniqueId in:transaction]; + }); [LKAPI cache:incomingMessage.authorId for:oldGroupThread.uniqueId]; [self finalizeIncomingMessage:incomingMessage diff --git a/SignalServiceKit/src/Network/API/NetworkManager.swift b/SignalServiceKit/src/Network/API/NetworkManager.swift index 3f7f61de2..c1892b669 100644 --- a/SignalServiceKit/src/Network/API/NetworkManager.swift +++ b/SignalServiceKit/src/Network/API/NetworkManager.swift @@ -29,10 +29,15 @@ extension NetworkManagerError { extension TSNetworkManager { public typealias NetworkManagerResult = (task: URLSessionDataTask, responseObject: Any?) - public func makePromise(request: TSRequest) -> Promise { + public func perform(_ request: TSRequest, withCompletionQueue queue: DispatchQueue = DispatchQueue.main) -> Promise { + return makePromise(request: request, queue: queue) + } + + public func makePromise(request: TSRequest, queue: DispatchQueue = DispatchQueue.main) -> Promise { let (promise, resolver) = Promise.pending() self.makeRequest(request, + completionQueue: queue, success: { task, responseObject in resolver.fulfill((task: task, responseObject: responseObject)) },