From 5987039f8b3b554e7310381d81f5dca506db0b81 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 9 Oct 2020 10:10:01 +1100 Subject: [PATCH] Make path re-building non-blocking --- .../src/Loki/Components/PathStatusView.swift | 4 +-- .../API/Onion Requests/OnionRequestAPI.swift | 32 +++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Signal/src/Loki/Components/PathStatusView.swift b/Signal/src/Loki/Components/PathStatusView.swift index e1d934bb2..1e0dcdf6c 100644 --- a/Signal/src/Loki/Components/PathStatusView.swift +++ b/Signal/src/Loki/Components/PathStatusView.swift @@ -16,10 +16,10 @@ final class PathStatusView : UIView { private func setUpViewHierarchy() { layer.cornerRadius = Values.pathStatusViewSize / 2 layer.masksToBounds = false - if OnionRequestAPI.paths.count < OnionRequestAPI.pathCount { + if OnionRequestAPI.paths.isEmpty { OnionRequestAPI.paths = Storage.getOnionRequestPaths() } - let color = (OnionRequestAPI.paths.count >= OnionRequestAPI.pathCount) ? Colors.accent : Colors.pathsBuilding + let color = (!OnionRequestAPI.paths.isEmpty) ? Colors.accent : Colors.pathsBuilding setColor(to: color, isAnimated: false) } diff --git a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift index 8478bdc2d..1db5aa8f8 100644 --- a/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift +++ b/SignalServiceKit/src/Loki/API/Onion Requests/OnionRequestAPI.swift @@ -13,9 +13,9 @@ public enum OnionRequestAPI { private static let pathFailureThreshold: UInt = 2 private static var pathFailureCount: [Path:UInt] = [:] - public static let pathCount: UInt = 2 + public static let targetPathCount: UInt = 2 - private static var guardSnodeCount: UInt { return pathCount } // One per path + private static var guardSnodeCount: UInt { return targetPathCount } // One per path // MARK: Destination internal enum Destination { @@ -105,7 +105,7 @@ public enum OnionRequestAPI { } } - /// Builds and returns `pathCount` paths. The returned promise errors out with `Error.insufficientSnodes` + /// Builds and returns `targetPathCount` paths. The returned promise errors out with `Error.insufficientSnodes` /// if not enough (reliable) snodes are available. private static func buildPaths(reusing reusablePaths: [Path]) -> Promise<[Path]> { print("[Loki] [Onion Request API] Building onion request paths.") @@ -161,17 +161,29 @@ public enum OnionRequestAPI { } } // randomElement() uses the system's default random generator, which is cryptographically secure - if paths.count >= pathCount { - return Promise { seal in - if let snode = snode { - seal.fulfill(paths.filter { !$0.contains(snode) }.randomElement()!) + if paths.count >= targetPathCount { + if let snode = snode { + return Promise { $0.fulfill(paths.filter { !$0.contains(snode) }.randomElement()!) } + } else { + return Promise { $0.fulfill(paths.randomElement()!) } + } + } else if !paths.isEmpty { + print("[Test] Reusing: \(paths)") + if let snode = snode { + if let path = paths.first(where: { !$0.contains(snode) }) { + buildPaths(reusing: paths).retainUntilComplete() // Re-build paths in the background + return Promise { $0.fulfill(path) } } else { - seal.fulfill(paths.randomElement()!) + return buildPaths(reusing: paths).map2 { paths in + return paths.filter { !$0.contains(snode) }.randomElement()! + } } + } else { + buildPaths(reusing: paths).retainUntilComplete() // Re-build paths in the background + return Promise { $0.fulfill(paths.randomElement()!) } } } else { - print("[Test] Reusing: \(paths)") - return buildPaths(reusing: paths).map2 { paths in + return buildPaths(reusing: []).map2 { paths in if let snode = snode { return paths.filter { !$0.contains(snode) }.randomElement()! } else {