From d039ecd87e4962e64bec7d75dec19fbe0ceddd7f Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 10 Mar 2020 13:43:28 +1100 Subject: [PATCH] Attempt to fix background crash in a different way --- SignalServiceKit/src/Loki/API/LokiAPI.swift | 23 ++++++++++--------- .../Database/OWSPrimaryStorage+Loki.swift | 9 ++++++-- .../src/Messages/OWSMessageSender.m | 6 ++--- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index fabf5e6df..71775b3c3 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -120,26 +120,27 @@ public final class LokiAPI : NSObject { }.map { Set($0) }.retryingIfNeeded(maxRetryCount: maxRetryCount) } - public static func getDestinations(for hexEncodedPublicKey: String) -> Promise<[Destination]> { - var result: Promise<[Destination]>! + public static func getDestinations(for hexEncodedPublicKey: String) -> Promise> { + var result: Promise>! storage.dbReadWriteConnection.readWrite { transaction in result = getDestinations(for: hexEncodedPublicKey, in: transaction) } return result } - public static func getDestinations(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction) -> Promise<[Destination]> { + public static func getDestinations(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction) -> Promise> { // All of this has to happen on DispatchQueue.global() due to the way OWSMessageManager works - let (promise, seal) = Promise<[Destination]>.pending() + let (promise, seal) = Promise>.pending() func getDestinations(in transaction: YapDatabaseReadTransaction? = nil) { func getDestinationsInternal(in transaction: YapDatabaseReadTransaction) { - var destinations: [Destination] = [] - let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) ?? hexEncodedPublicKey - let masterDestination = Destination(hexEncodedPublicKey: masterHexEncodedPublicKey, kind: .master) - destinations.append(masterDestination) - let deviceLinks = storage.getDeviceLinks(for: masterHexEncodedPublicKey, in: transaction) - let slaveDestinations = deviceLinks.map { Destination(hexEncodedPublicKey: $0.slave.hexEncodedPublicKey, kind: .slave) } - destinations.append(contentsOf: slaveDestinations) + let query = YapDatabaseQuery(string: "WHERE \(DeviceLinkIndex.slaveHexEncodedPublicKey) = ? OR \(DeviceLinkIndex.masterHexEncodedPublicKey) = ?", parameters: [ hexEncodedPublicKey, hexEncodedPublicKey ]) + let deviceLinks = Set(DeviceLinkIndex.getDeviceLinks(for: query, in: transaction)) + var destinations = Set(deviceLinks.flatMap { + return [ Destination(hexEncodedPublicKey: $0.master.hexEncodedPublicKey, kind: .master), Destination(hexEncodedPublicKey: $0.slave.hexEncodedPublicKey, kind: .slave) ] + }) + if destinations.isEmpty { + destinations.insert(Destination(hexEncodedPublicKey: hexEncodedPublicKey, kind: .master)) + } seal.fulfill(destinations) } if let transaction = transaction, transaction.connection.pendingTransactionCount != 0 { diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index 271bbad1c..007d319c6 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -29,8 +29,13 @@ public extension OWSPrimaryStorage { } public func getDeviceLinks(for masterHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> Set { - let query = YapDatabaseQuery(string: "WHERE \(DeviceLinkIndex.masterHexEncodedPublicKey) = ?", parameters: [ masterHexEncodedPublicKey ]) - return Set(DeviceLinkIndex.getDeviceLinks(for: query, in: transaction)) + let collection = getDeviceLinkCollection(for: masterHexEncodedPublicKey) + var result: Set = [] + transaction.enumerateRows(inCollection: collection) { _, object, _, _ in + guard let deviceLink = object as? DeviceLink else { return } + result.insert(deviceLink) + } + return result } public func getDeviceLink(for slaveHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> DeviceLink? { diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 6b2e8096d..f90a98cfb 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -995,11 +995,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; BOOL isFriendRequestMessage = [message isKindOfClass:LKFriendRequestMessage.class]; BOOL isSessionRequestMessage = [message isKindOfClass:LKSessionRequestMessage.class]; [[LKAPI getDestinationsFor:contactID] - .thenOn(OWSDispatch.sendingQueue, ^(NSArray *destinations) { + .thenOn(OWSDispatch.sendingQueue, ^(NSSet *destinations) { // Get master destination LKDestination *masterDestination = [destinations filtered:^BOOL(LKDestination *destination) { return [destination.kind isEqual:@"master"]; - }].firstObject; + }].allObjects.firstObject; // Send to master destination if (masterDestination != nil) { TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:masterDestination.hexEncodedPublicKey]; @@ -1012,7 +1012,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } } // Get slave destinations - NSArray *slaveDestinations = [destinations filtered:^BOOL(LKDestination *destination) { + NSSet *slaveDestinations = [destinations filtered:^BOOL(LKDestination *destination) { return [destination.kind isEqual:@"slave"]; }]; // Send to slave destinations (using a best attempt approach (i.e. ignoring the message send result) for now)