Make path re-building non-blocking

pull/296/head
nielsandriesse 5 years ago
parent 008f74bd89
commit 5987039f8b

@ -16,10 +16,10 @@ final class PathStatusView : UIView {
private func setUpViewHierarchy() { private func setUpViewHierarchy() {
layer.cornerRadius = Values.pathStatusViewSize / 2 layer.cornerRadius = Values.pathStatusViewSize / 2
layer.masksToBounds = false layer.masksToBounds = false
if OnionRequestAPI.paths.count < OnionRequestAPI.pathCount { if OnionRequestAPI.paths.isEmpty {
OnionRequestAPI.paths = Storage.getOnionRequestPaths() 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) setColor(to: color, isAnimated: false)
} }

@ -13,9 +13,9 @@ public enum OnionRequestAPI {
private static let pathFailureThreshold: UInt = 2 private static let pathFailureThreshold: UInt = 2
private static var pathFailureCount: [Path:UInt] = [:] 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 // MARK: Destination
internal enum 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. /// if not enough (reliable) snodes are available.
private static func buildPaths(reusing reusablePaths: [Path]) -> Promise<[Path]> { private static func buildPaths(reusing reusablePaths: [Path]) -> Promise<[Path]> {
print("[Loki] [Onion Request API] Building onion request paths.") 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 // randomElement() uses the system's default random generator, which is cryptographically secure
if paths.count >= pathCount { if paths.count >= targetPathCount {
return Promise<Path> { seal in if let snode = snode {
if let snode = snode { return Promise { $0.fulfill(paths.filter { !$0.contains(snode) }.randomElement()!) }
seal.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 { } 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 { } else {
print("[Test] Reusing: \(paths)") return buildPaths(reusing: []).map2 { paths in
return buildPaths(reusing: paths).map2 { paths in
if let snode = snode { if let snode = snode {
return paths.filter { !$0.contains(snode) }.randomElement()! return paths.filter { !$0.contains(snode) }.randomElement()!
} else { } else {

Loading…
Cancel
Save