From 6533af8ba9f96d054eaea3657d15b1e078d504eb Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Fri, 12 Jun 2020 14:36:21 +1000 Subject: [PATCH] WIP --- .../src/Loki/API/LokiAPI+SwarmAPI.swift | 53 +++---------------- SignalServiceKit/src/Loki/API/LokiAPI.swift | 2 +- .../Protocol/Mentions/MentionsManager.swift | 18 ++----- .../Multi Device/MultiDeviceProtocol.swift | 18 ++----- .../Loki/Utilities/Promise+Threading.swift | 30 +++++------ SignalServiceKit/src/Util/OWSDispatch.m | 3 +- 6 files changed, 30 insertions(+), 94 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index d2b0161ba..0493edc85 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -4,55 +4,14 @@ public extension LokiAPI { fileprivate static let seedNodePool: Set = [ "https://storage.seed1.loki.network", "https://storage.seed3.loki.network", "https://public.loki.foundation" ] - internal static var _snodeFailureCount: [LokiAPITarget:UInt] = [:] - internal static var snodeFailureCount: [LokiAPITarget:UInt] { - get { - let (promise, seal) = Promise<[LokiAPITarget:UInt]>.pending() - stateQueue.async { - seal.fulfill(_snodeFailureCount) - } - return try! promise.wait() - } - set { - LokiAPI.stateQueue.async { - _snodeFailureCount = newValue - } - } - } - + /// - Note: Should only be accessed from `LokiAPI.workQueue` to avoid race conditions. + internal static var snodeFailureCount: [LokiAPITarget:UInt] = [:] // TODO: Read/write this directly from/to the database - internal static var _snodePool: Set = [] - internal static var snodePool: Set { - get { - let (promise, seal) = Promise>.pending() - stateQueue.async { - seal.fulfill(_snodePool) - } - return try! promise.wait() - } - set { - LokiAPI.stateQueue.async { - _snodePool = newValue - } - } - } - + /// - Note: Should only be accessed from `LokiAPI.workQueue` to avoid race conditions. + internal static var snodePool: Set = [] // TODO: Read/write this directly from/to the database - internal static var _swarmCache: [String:[LokiAPITarget]] = [:] - internal static var swarmCache: [String:[LokiAPITarget]] { - get { - let (promise, seal) = Promise<[String:[LokiAPITarget]]>.pending() - stateQueue.async { - seal.fulfill(_swarmCache) - } - return try! promise.wait() - } - set { - LokiAPI.stateQueue.async { - _swarmCache = newValue - } - } - } + /// - Note: Should only be accessed from `LokiAPI.workQueue` to avoid race conditions. + internal static var swarmCache: [String:[LokiAPITarget]] = [:] // MARK: Settings private static let minimumSnodePoolCount = 32 diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index aae83e834..975782f96 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -2,7 +2,7 @@ import PromiseKit @objc(LKAPI) public final class LokiAPI : NSObject { - internal static let stateQueue = DispatchQueue(label: "LokiAPI.stateQueue", qos: .userInitiated) + internal static let workQueue = DispatchQueue(label: "LokiAPI.workQueue", qos: .userInitiated) internal static var storage: OWSPrimaryStorage { OWSPrimaryStorage.shared() } diff --git a/SignalServiceKit/src/Loki/Protocol/Mentions/MentionsManager.swift b/SignalServiceKit/src/Loki/Protocol/Mentions/MentionsManager.swift index 3842eee81..5f3c9ca61 100644 --- a/SignalServiceKit/src/Loki/Protocol/Mentions/MentionsManager.swift +++ b/SignalServiceKit/src/Loki/Protocol/Mentions/MentionsManager.swift @@ -3,22 +3,10 @@ import PromiseKit @objc(LKMentionsManager) public final class MentionsManager : NSObject { - @objc public static var _userPublicKeyCache: [String:Set] = [:] /// A mapping from thread ID to set of user hex encoded public keys. - @objc public static var userPublicKeyCache: [String:Set] { - get { - let (promise, seal) = Promise<[String:Set]>.pending() - LokiAPI.stateQueue.async { - seal.fulfill(_userPublicKeyCache) - } - return try! promise.wait() - } - set { - LokiAPI.stateQueue.async { - _userPublicKeyCache = newValue - } - } - } + /// + /// - Note: Should only be accessed from the main queue to avoid race conditions. + @objc public static var userPublicKeyCache: [String:Set] = [:] internal static var storage: OWSPrimaryStorage { OWSPrimaryStorage.shared() } diff --git a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift index b0ae27870..bceace01b 100644 --- a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift @@ -15,22 +15,10 @@ import PromiseKit @objc(LKMultiDeviceProtocol) public final class MultiDeviceProtocol : NSObject { - public static var _lastDeviceLinkUpdate: [String:Date] = [:] /// A mapping from hex encoded public key to date updated. - public static var lastDeviceLinkUpdate: [String:Date] { - get { - let (promise, seal) = Promise<[String:Date]>.pending() - LokiAPI.stateQueue.async { - seal.fulfill(_lastDeviceLinkUpdate) - } - return try! promise.wait() - } - set { - LokiAPI.stateQueue.async { - _lastDeviceLinkUpdate = newValue - } - } - } + /// + /// - Note: Should only be accessed from `LokiAPI.workQueue` to avoid race conditions. + public static var lastDeviceLinkUpdate: [String:Date] = [:] internal static var storage: OWSPrimaryStorage { OWSPrimaryStorage.shared() } diff --git a/SignalServiceKit/src/Loki/Utilities/Promise+Threading.swift b/SignalServiceKit/src/Loki/Utilities/Promise+Threading.swift index b6ff6b76e..81de1c816 100644 --- a/SignalServiceKit/src/Loki/Utilities/Promise+Threading.swift +++ b/SignalServiceKit/src/Loki/Utilities/Promise+Threading.swift @@ -3,74 +3,74 @@ import PromiseKit public extension Thenable { func then2(_ body: @escaping (T) throws -> U) -> Promise where U : Thenable { - return then(on: DispatchQueue.global(qos: .default), body) + return then(on: LokiAPI.workQueue, body) } func map2(_ transform: @escaping (T) throws -> U) -> Promise { - return map(on: DispatchQueue.global(qos: .default), transform) + return map(on: LokiAPI.workQueue, transform) } func done2(_ body: @escaping (T) throws -> Void) -> Promise { - return done(on: DispatchQueue.global(qos: .default), body) + return done(on: LokiAPI.workQueue, body) } func get2(_ body: @escaping (T) throws -> Void) -> Promise { - return get(on: DispatchQueue.global(qos: .default), body) + return get(on: LokiAPI.workQueue, body) } } public extension Thenable where T: Sequence { func mapValues2(_ transform: @escaping (T.Iterator.Element) throws -> U) -> Promise<[U]> { - return mapValues(on: DispatchQueue.global(qos: .default), transform) + return mapValues(on: LokiAPI.workQueue, transform) } } public extension Guarantee { func then2(_ body: @escaping (T) -> Guarantee) -> Guarantee { - return then(on: DispatchQueue.global(qos: .default), body) + return then(on: LokiAPI.workQueue, body) } func map2(_ body: @escaping (T) -> U) -> Guarantee { - return map(on: DispatchQueue.global(qos: .default), body) + return map(on: LokiAPI.workQueue, body) } func done2(_ body: @escaping (T) -> Void) -> Guarantee { - return done(on: DispatchQueue.global(qos: .default), body) + return done(on: LokiAPI.workQueue, body) } func get2(_ body: @escaping (T) -> Void) -> Guarantee { - return get(on: DispatchQueue.global(qos: .default), body) + return get(on: LokiAPI.workQueue, body) } } public extension CatchMixin { func catch2(_ body: @escaping (Error) -> Void) -> PMKFinalizer { - return self.catch(on: DispatchQueue.global(qos: .default), body) + return self.catch(on: LokiAPI.workQueue, body) } func recover2(_ body: @escaping(Error) throws -> U) -> Promise where U.T == T { - return recover(on: DispatchQueue.global(qos: .default), body) + return recover(on: LokiAPI.workQueue, body) } func recover2(_ body: @escaping(Error) -> Guarantee) -> Guarantee { - return recover(on: DispatchQueue.global(qos: .default), body) + return recover(on: LokiAPI.workQueue, body) } func ensure2(_ body: @escaping () -> Void) -> Promise { - return ensure(on: DispatchQueue.global(qos: .default), body) + return ensure(on: LokiAPI.workQueue, body) } } public extension CatchMixin where T == Void { func recover2(_ body: @escaping(Error) -> Void) -> Guarantee { - return recover(on: DispatchQueue.global(qos: .default), body) + return recover(on: LokiAPI.workQueue, body) } func recover2(_ body: @escaping(Error) throws -> Void) -> Promise { - return recover(on: DispatchQueue.global(qos: .default), body) + return recover(on: LokiAPI.workQueue, body) } } diff --git a/SignalServiceKit/src/Util/OWSDispatch.m b/SignalServiceKit/src/Util/OWSDispatch.m index 6278be3a2..5f300a2f9 100644 --- a/SignalServiceKit/src/Util/OWSDispatch.m +++ b/SignalServiceKit/src/Util/OWSDispatch.m @@ -23,7 +23,8 @@ NS_ASSUME_NONNULL_BEGIN static dispatch_once_t onceToken; static dispatch_queue_t queue; dispatch_once(&onceToken, ^{ - queue = dispatch_queue_create("org.whispersystems.signal.sendQueue", NULL); + dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0); + queue = dispatch_queue_create("org.whispersystems.signal.sendQueue", attributes); }); return queue; }