mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge pull request #200 from loki-project/performance
Further Performance Improvements
This commit is contained in:
commit
c2c750baaf
5 changed files with 65 additions and 3 deletions
|
@ -14,13 +14,20 @@ public extension LokiAPI {
|
|||
internal static let snodeFailureThreshold = 2
|
||||
|
||||
// MARK: Caching
|
||||
internal static var swarmCache: [String:[LokiAPITarget]] = [:]
|
||||
internal static var swarmCache: [String:[LokiAPITarget]] = [:] // TODO: Make this set based?
|
||||
|
||||
internal static func dropSnodeFromSwarmIfNeeded(_ target: LokiAPITarget, hexEncodedPublicKey: String) {
|
||||
let swarm = LokiAPI.swarmCache[hexEncodedPublicKey]
|
||||
if var swarm = swarm, let index = swarm.firstIndex(of: target) {
|
||||
swarm.remove(at: index)
|
||||
LokiAPI.swarmCache[hexEncodedPublicKey] = swarm
|
||||
// Dispatch async on the main queue to avoid nested write transactions
|
||||
DispatchQueue.main.async {
|
||||
let storage = OWSPrimaryStorage.shared()
|
||||
storage.dbReadWriteConnection.readWrite { transaction in
|
||||
storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,11 +103,30 @@ public extension LokiAPI {
|
|||
}
|
||||
|
||||
internal static func getSwarm(for hexEncodedPublicKey: String) -> Promise<[LokiAPITarget]> {
|
||||
if swarmCache[hexEncodedPublicKey] == nil {
|
||||
storage.dbReadConnection.read { transaction in
|
||||
swarmCache[hexEncodedPublicKey] = storage.getSwarm(for: hexEncodedPublicKey, in: transaction)
|
||||
}
|
||||
}
|
||||
if let cachedSwarm = swarmCache[hexEncodedPublicKey], cachedSwarm.count >= minimumSwarmSnodeCount {
|
||||
return Promise<[LokiAPITarget]> { $0.fulfill(cachedSwarm) }
|
||||
} else {
|
||||
print("[Loki] Getting swarm for: \(hexEncodedPublicKey).")
|
||||
let parameters: [String:Any] = [ "pubKey" : hexEncodedPublicKey ]
|
||||
return getRandomSnode().then(on: workQueue) { invoke(.getSwarm, on: $0, associatedWith: hexEncodedPublicKey, parameters: parameters) }.map { parseTargets(from: $0) }.get { swarmCache[hexEncodedPublicKey] = $0 }
|
||||
return getRandomSnode().then(on: workQueue) {
|
||||
invoke(.getSwarm, on: $0, associatedWith: hexEncodedPublicKey, parameters: parameters)
|
||||
}.map {
|
||||
parseTargets(from: $0)
|
||||
}.get { swarm in
|
||||
swarmCache[hexEncodedPublicKey] = swarm
|
||||
// Dispatch async on the main queue to avoid nested write transactions
|
||||
DispatchQueue.main.async {
|
||||
let storage = OWSPrimaryStorage.shared()
|
||||
storage.dbReadWriteConnection.readWrite { transaction in
|
||||
storage.setSwarm(swarm, for: hexEncodedPublicKey, in: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
public typealias Snode = LokiAPITarget
|
||||
|
||||
/// Either a service node or another client if P2P is enabled.
|
||||
public final class LokiAPITarget : NSObject, NSCoding {
|
||||
internal let address: String
|
||||
|
|
|
@ -49,7 +49,7 @@ public struct LokiMessage {
|
|||
/// - Returns: The promise of a new message with its `timestamp` and `nonce` set.
|
||||
public func calculatePoW() -> Promise<LokiMessage> {
|
||||
return Promise<LokiMessage> { seal in
|
||||
DispatchQueue.global().async {
|
||||
DispatchQueue.global(qos: .userInitiated).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) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
// TODO: Make this strongly typed like LKUserDefaults
|
||||
|
||||
public extension OWSPrimaryStorage {
|
||||
|
||||
// MARK: - Snode Pool
|
||||
|
@ -30,6 +32,37 @@ public extension OWSPrimaryStorage {
|
|||
|
||||
|
||||
|
||||
// MARK: - Swarm
|
||||
private func getSwarmCollection(for publicKey: String) -> String {
|
||||
return "LokiSwarmCollection-\(publicKey)"
|
||||
}
|
||||
|
||||
public func setSwarm(_ swarm: [Snode], for publicKey: String, in transaction: YapDatabaseReadWriteTransaction) {
|
||||
print("[Loki] Caching swarm for: \(publicKey).")
|
||||
clearSwarm(for: publicKey, in: transaction)
|
||||
let collection = getSwarmCollection(for: publicKey)
|
||||
swarm.forEach { snode in
|
||||
transaction.setObject(snode, forKey: snode.description, inCollection: collection)
|
||||
}
|
||||
}
|
||||
|
||||
public func clearSwarm(for publicKey: String, in transaction: YapDatabaseReadWriteTransaction) {
|
||||
let collection = getSwarmCollection(for: publicKey)
|
||||
transaction.removeAllObjects(inCollection: collection)
|
||||
}
|
||||
|
||||
public func getSwarm(for publicKey: String, in transaction: YapDatabaseReadTransaction) -> [Snode] {
|
||||
var result: [Snode] = []
|
||||
let collection = getSwarmCollection(for: publicKey)
|
||||
transaction.enumerateKeysAndObjects(inCollection: collection) { _, object, _ in
|
||||
guard let snode = object as? Snode else { return }
|
||||
result.append(snode)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - Onion Request Path
|
||||
private static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ public class MessageSenderJobQueue: NSObject, JobQueue {
|
|||
let operationQueue = OperationQueue()
|
||||
operationQueue.name = "DefaultSendingQueue"
|
||||
operationQueue.maxConcurrentOperationCount = 1
|
||||
operationQueue.qualityOfService = .userInitiated
|
||||
|
||||
return operationQueue
|
||||
}()
|
||||
|
|
Loading…
Reference in a new issue