Fix crash

pull/220/head
nielsandriesse 5 years ago
parent 8d666181d2
commit 8a7b95d21f

@ -41,7 +41,7 @@ public extension LokiAPI {
]
print("[Loki] Populating snode pool using: \(target).")
let (promise, seal) = Promise<LokiAPITarget>.pending()
attempt(maxRetryCount: 4) {
attempt(maxRetryCount: 4, recoveringOn: LokiAPI.workQueue) {
HTTP.execute(.post, url, parameters: parameters).map2 { json -> LokiAPITarget in
guard let intermediate = json["result"] as? JSON, let rawTargets = intermediate["service_node_states"] as? [JSON] else { throw LokiAPIError.randomSnodePoolUpdatingFailed }
snodePool = try Set(rawTargets.flatMap { rawTarget in

@ -61,7 +61,7 @@ public final class LokiAPI : NSObject {
// MARK: Public API
public static func getMessages() -> Promise<Set<MessageListPromise>> {
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getTargetSnodes(for: getUserHexEncodedPublicKey()).mapValues2 { targetSnode in
getRawMessages(from: targetSnode, usingLongPolling: false).map2 { parseRawMessagesResponse($0, from: targetSnode) }
}.map2 { Set($0) }
@ -89,7 +89,7 @@ public final class LokiAPI : NSObject {
let parameters = lokiMessageWithPoW.toJSON()
return Set(snodes.map { snode in
// Send the message to the target snode
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
invoke(.sendMessage, on: snode, associatedWith: destination, parameters: parameters)
}.map2 { rawResponse in
if let json = rawResponse as? JSON, let powDifficulty = json["difficulty"] as? Int {

@ -98,7 +98,7 @@ public final class LokiFileServerAPI : 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 attempt(maxRetryCount: 8) {
return attempt(maxRetryCount: 8, recoveringOn: LokiAPI.workQueue) {
LokiFileServerProxy(for: server).perform(request).map2 { _ in }
}.handlingInvalidAuthTokenIfNeeded(for: server).recover2 { error in
print("Couldn't update device links due to error: \(error).")

@ -10,7 +10,7 @@ public final class LokiPoller : NSObject {
private var pollCount = 0
// MARK: Settings
private static let retryInterval: TimeInterval = 1
private static let retryInterval: TimeInterval = 0.25
/// After polling a given snode this many times we always switch to a new one.
///
/// The reason for doing this is that sometimes a snode will be giving us successful responses while

@ -83,7 +83,9 @@ public enum OnionRequestAPI {
unusedSnodes.remove(candidate) // All used snodes should be unique
print("[Loki] [Onion Request API] Testing guard snode: \(candidate).")
// Loop until a reliable guard snode is found
return testSnode(candidate).map2 { candidate }.recover2 { _ in getGuardSnode() }
return testSnode(candidate).map2 { candidate }.recover(on: DispatchQueue.main) { _ in
withDelay(0.25, completionQueue: LokiAPI.workQueue) { getGuardSnode() }
}
}
let promises = (0..<guardSnodeCount).map { _ in getGuardSnode() }
return when(fulfilled: promises).map2 { guardSnodes in

@ -175,7 +175,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
let (promise, seal) = Promise<LokiPublicChatMessage>.pending()
DispatchQueue.global(qos: .userInitiated).async { [privateKey = userKeyPair.privateKey] in
guard let signedMessage = message.sign(with: privateKey) else { return seal.reject(LokiDotNetAPIError.signingFailed) }
attempt(maxRetryCount: maxRetryCount) {
attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<LokiPublicChatMessage> in
let url = URL(string: "\(server)/channels/\(channel)/messages")!
let parameters = signedMessage.toJSON()
@ -244,7 +244,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
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)"
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<Void> in
let url = URL(string: urlAsString)!
let request = TSRequest(url: url, method: "DELETE", parameters: [:])
@ -292,7 +292,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
public static func setDisplayName(to newDisplayName: String?, on server: String) -> Promise<Void> {
print("[Loki] Updating display name on server: \(server).")
let parameters: JSON = [ "name" : (newDisplayName ?? "") ]
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<Void> in
let url = URL(string: "\(server)/users/me")!
let request = TSRequest(url: url, method: "PATCH", parameters: parameters)
@ -317,7 +317,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
annotation["value"] = [ "profileKey" : profileKey.base64EncodedString(), "url" : url ]
}
let parameters: JSON = [ "annotations" : [ annotation ] ]
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<Void> in
let url = URL(string: "\(server)/users/me")!
let request = TSRequest(url: url, method: "PATCH", parameters: parameters)
@ -382,7 +382,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
}
public static func getInfo(for channel: UInt64, on server: String) -> Promise<LokiPublicChatInfo> {
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<LokiPublicChatInfo> in
let url = URL(string: "\(server)/channels/\(channel)?include_annotations=1")!
let request = TSRequest(url: url)
@ -413,7 +413,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
}
public static func join(_ channel: UInt64, on server: String) -> Promise<Void> {
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<Void> in
let url = URL(string: "\(server)/channels/\(channel)/subscribe")!
let request = TSRequest(url: url, method: "POST", parameters: [:])
@ -426,7 +426,7 @@ public final class LokiPublicChatAPI : LokiDotNetAPI {
}
public static func leave(_ channel: UInt64, on server: String) -> Promise<Void> {
return attempt(maxRetryCount: maxRetryCount) {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: LokiAPI.workQueue) {
getAuthToken(for: server).then2 { token -> Promise<Void> in
let url = URL(string: "\(server)/channels/\(channel)/subscribe")!
let request = TSRequest(url: url, method: "DELETE", parameters: [:])

@ -0,0 +1,11 @@
import PromiseKit
/// Delay the execution of the promise constructed in `body` by `delay` seconds.
internal func withDelay<T>(_ delay: TimeInterval, completionQueue: DispatchQueue, body: @escaping () -> Promise<T>) -> Promise<T> {
AssertIsOnMainThread() // Timers don't do well on background queues
let (promise, seal) = Promise<T>.pending()
Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { _ in
body().done(on: completionQueue) { seal.fulfill($0) }.catch(on: completionQueue) { seal.reject($0) }
}
return promise
}

@ -1,7 +1,7 @@
import PromiseKit
/// Retry the promise constructed in `body` up to `maxRetryCount` times.
internal func attempt<T>(maxRetryCount: UInt, recoveringOn queue: DispatchQueue = .global(qos: .default), body: @escaping () -> Promise<T>) -> Promise<T> {
internal func attempt<T>(maxRetryCount: UInt, recoveringOn queue: DispatchQueue, body: @escaping () -> Promise<T>) -> Promise<T> {
var retryCount = 0
func attempt() -> Promise<T> {
return body().recover(on: queue) { error -> Promise<T> in

Loading…
Cancel
Save