From ea1b62e838c02cbc6fcafe36e86c2d2fd90104da Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 5 Jun 2020 15:40:13 -0300 Subject: [PATCH] Rework model read caches. --- .../util/FTS/GRDBFullTextSearcherTest.swift | 1 - .../test/util/GroupAndContactStreamTest.swift | 3 +- SignalMessaging/contacts/OWSContactsManager.m | 8 +-- SignalMessaging/environment/AppSetup.m | 2 + SignalServiceKit/src/Contacts/SignalAccount.m | 11 ++-- .../src/Contacts/SignalRecipient.m | 36 +++++++++++-- .../src/Protocols/ContactsManagerProtocol.h | 3 -- SignalServiceKit/src/SSKEnvironment.h | 3 ++ SignalServiceKit/src/SSKEnvironment.m | 4 ++ .../src/TestUtils/FakeContactsManager.swift | 5 -- .../src/TestUtils/MockSSKEnvironment.m | 2 + .../src/Util/ModelReadCache.swift | 54 ++++++++++++++++++- 12 files changed, 110 insertions(+), 22 deletions(-) diff --git a/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift b/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift index 5b9616f823..1148f35ff7 100644 --- a/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift +++ b/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift @@ -11,7 +11,6 @@ import Contacts // TODO: We might be able to merge this with OWSFakeContactsManager. @objc class GRDBFullTextSearcherContactsManager: NSObject, ContactsManagerProtocol { - let signalAccountReadCache = SignalAccountReadCache() func comparableName(for signalAccount: SignalAccount, transaction: SDSAnyReadTransaction) -> String { return self.displayName(for: signalAccount.recipientAddress) diff --git a/Signal/test/util/GroupAndContactStreamTest.swift b/Signal/test/util/GroupAndContactStreamTest.swift index 6dc32a3863..96052620c4 100644 --- a/Signal/test/util/GroupAndContactStreamTest.swift +++ b/Signal/test/util/GroupAndContactStreamTest.swift @@ -321,7 +321,6 @@ class GroupAndContactStreamTest: SignalBaseTest { } class TestContactsManager: NSObject, ContactsManagerProtocol { - let signalAccountReadCache = SignalAccountReadCache() func comparableName(for signalAccount: SignalAccount, transaction: SDSAnyReadTransaction) -> String { return signalAccount.recipientAddress.stringForDisplay @@ -395,6 +394,6 @@ class TestContactsManager: NSObject, ContactsManagerProtocol { func avatarImage(forCNContactId contactId: String?) -> UIImage? { return nil } - + var unknownUserLabel: String = "unknown" } diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index b8fceb04da..1d6be37b22 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -52,8 +52,6 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan @implementation OWSContactsManager -@synthesize signalAccountReadCache = _signalAccountReadCache; - #pragma mark - Dependencies - (SDSDatabaseStorage *)databaseStorage @@ -66,6 +64,11 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan return OWSProfileManager.sharedManager; } +- (SignalAccountReadCache *)signalAccountReadCache +{ + return SSKEnvironment.shared.modelReadCaches.signalAccountReadCache; +} + #pragma mark - - (id)init @@ -83,7 +86,6 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan _allContacts = @[]; _allContactsMap = @{}; - _signalAccountReadCache = [SignalAccountReadCache new]; _signalAccounts = @[]; _systemContactsFetcher = [SystemContactsFetcher new]; _systemContactsFetcher.delegate = self; diff --git a/SignalMessaging/environment/AppSetup.m b/SignalMessaging/environment/AppSetup.m index c582e7494d..b9c535b48e 100644 --- a/SignalMessaging/environment/AppSetup.m +++ b/SignalMessaging/environment/AppSetup.m @@ -116,6 +116,7 @@ NS_ASSUME_NONNULL_BEGIN BulkProfileFetch *bulkProfileFetch = [BulkProfileFetch new]; BulkUUIDLookup *bulkUUIDLookup = [BulkUUIDLookup new]; id versionedProfiles = [VersionedProfilesImpl new]; + ModelReadCaches *modelReadCaches = [ModelReadCaches new]; EarlyMessageManager *earlyMessageManager = [EarlyMessageManager new]; [Environment setShared:[[Environment alloc] initWithAudioSession:audioSession @@ -175,6 +176,7 @@ NS_ASSUME_NONNULL_BEGIN bulkProfileFetch:bulkProfileFetch bulkUUIDLookup:bulkUUIDLookup versionedProfiles:versionedProfiles + modelReadCaches:modelReadCaches earlyMessageManager:earlyMessageManager]]; appSpecificSingletonBlock(); diff --git a/SignalServiceKit/src/Contacts/SignalAccount.m b/SignalServiceKit/src/Contacts/SignalAccount.m index ad4f4a0ac0..dda6a1af61 100644 --- a/SignalServiceKit/src/Contacts/SignalAccount.m +++ b/SignalServiceKit/src/Contacts/SignalAccount.m @@ -34,6 +34,11 @@ NSUInteger const SignalAccountSchemaVersion = 1; return SSKEnvironment.shared.contactsManager; } +- (SignalAccountReadCache *)signalAccountReadCache +{ + return SSKEnvironment.shared.modelReadCaches.signalAccountReadCache; +} + #pragma mark - + (BOOL)shouldBeIndexedForFTS @@ -218,21 +223,21 @@ NSUInteger const SignalAccountSchemaVersion = 1; { [super anyDidInsertWithTransaction:transaction]; - [self.contactsManager.signalAccountReadCache didInsertOrUpdateSignalAccount:self transaction:transaction]; + [self.signalAccountReadCache didInsertOrUpdateSignalAccount:self transaction:transaction]; } - (void)anyDidUpdateWithTransaction:(SDSAnyWriteTransaction *)transaction { [super anyDidUpdateWithTransaction:transaction]; - [self.contactsManager.signalAccountReadCache didInsertOrUpdateSignalAccount:self transaction:transaction]; + [self.signalAccountReadCache didInsertOrUpdateSignalAccount:self transaction:transaction]; } - (void)anyDidRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction { [super anyDidRemoveWithTransaction:transaction]; - [self.contactsManager.signalAccountReadCache didRemoveSignalAccount:self transaction:transaction]; + [self.signalAccountReadCache didRemoveSignalAccount:self transaction:transaction]; } @end diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.m b/SignalServiceKit/src/Contacts/SignalRecipient.m index 6e59c0186a..9a4cc3cfff 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.m +++ b/SignalServiceKit/src/Contacts/SignalRecipient.m @@ -62,6 +62,16 @@ const NSUInteger SignalRecipientSchemaVersion = 1; return SSKEnvironment.shared.sessionStore; } ++ (SignalRecipientReadCache *)signalRecipientReadCache +{ + return SSKEnvironment.shared.modelReadCaches.signalRecipientReadCache; +} + +- (SignalRecipientReadCache *)signalRecipientReadCache +{ + return SSKEnvironment.shared.modelReadCaches.signalRecipientReadCache; +} + #pragma mark - + (instancetype)getOrBuildUnsavedRecipientForAddress:(SignalServiceAddress *)address @@ -171,12 +181,11 @@ const NSUInteger SignalRecipientSchemaVersion = 1; { OWSAssertDebug(transaction); OWSAssertDebug(address.isValid); - SignalRecipient *_Nullable signalRecipient = [self.recipientFinder signalRecipientForAddress:address - transaction:transaction]; + SignalRecipient *_Nullable signalRecipient = + [self.signalRecipientReadCache getSignalRecipientForAddress:address transaction:transaction]; if (mustHaveDevices && signalRecipient.devices.count < 1) { return nil; } - return signalRecipient; } @@ -456,6 +465,27 @@ const NSUInteger SignalRecipientSchemaVersion = 1; } } +- (void)anyDidInsertWithTransaction:(SDSAnyWriteTransaction *)transaction +{ + [super anyDidInsertWithTransaction:transaction]; + + [self.signalRecipientReadCache didInsertOrUpdateSignalRecipient:self transaction:transaction]; +} + +- (void)anyDidUpdateWithTransaction:(SDSAnyWriteTransaction *)transaction +{ + [super anyDidUpdateWithTransaction:transaction]; + + [self.signalRecipientReadCache didInsertOrUpdateSignalRecipient:self transaction:transaction]; +} + +- (void)anyDidRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction +{ + [super anyDidRemoveWithTransaction:transaction]; + + [self.signalRecipientReadCache didRemoveSignalRecipient:self transaction:transaction]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h b/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h index b0a2a4f79e..e680f07a14 100644 --- a/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h +++ b/SignalServiceKit/src/Protocols/ContactsManagerProtocol.h @@ -10,7 +10,6 @@ NS_ASSUME_NONNULL_BEGIN @class PhoneNumber; @class SDSAnyReadTransaction; @class SignalAccount; -@class SignalAccountReadCache; @class SignalServiceAddress; @class TSThread; @class UIImage; @@ -55,8 +54,6 @@ NS_ASSUME_NONNULL_BEGIN - (NSString *)comparableNameForSignalAccount:(SignalAccount *)signalAccount transaction:(SDSAnyReadTransaction *)transaction; -@property (nonatomic, readonly) SignalAccountReadCache *signalAccountReadCache; - @property (nonatomic, readonly) NSString *unknownUserLabel; #pragma mark - CNContacts diff --git a/SignalServiceKit/src/SSKEnvironment.h b/SignalServiceKit/src/SSKEnvironment.h index 20353f47af..49c1fb024d 100644 --- a/SignalServiceKit/src/SSKEnvironment.h +++ b/SignalServiceKit/src/SSKEnvironment.h @@ -13,6 +13,7 @@ NS_ASSUME_NONNULL_BEGIN @class MessageFetcherJob; @class MessageProcessing; @class MessageSenderJobQueue; +@class ModelReadCaches; @class OWS2FAManager; @class OWSAttachmentDownloads; @class OWSBatchMessageProcessor; @@ -107,6 +108,7 @@ NS_ASSUME_NONNULL_BEGIN bulkProfileFetch:(BulkProfileFetch *)bulkProfileFetch bulkUUIDLookup:(BulkUUIDLookup *)bulkUUIDLookup versionedProfiles:(id)versionedProfiles + modelReadCaches:(ModelReadCaches *)modelReadCaches earlyMessageManager:(EarlyMessageManager *)earlyMessageManager NS_DESIGNATED_INITIALIZER; @property (nonatomic, readonly, class) SSKEnvironment *shared; @@ -165,6 +167,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) BulkProfileFetch *bulkProfileFetch; @property (nonatomic, readonly) BulkUUIDLookup *bulkUUIDLookup; @property (nonatomic, readonly) id versionedProfiles; +@property (nonatomic, readonly) ModelReadCaches *modelReadCaches; @property (nonatomic, readonly) EarlyMessageManager *earlyMessageManager; @property (nonatomic, readonly, nullable) OWSPrimaryStorage *primaryStorage; diff --git a/SignalServiceKit/src/SSKEnvironment.m b/SignalServiceKit/src/SSKEnvironment.m index fbcdd85add..0d58b1aa84 100644 --- a/SignalServiceKit/src/SSKEnvironment.m +++ b/SignalServiceKit/src/SSKEnvironment.m @@ -52,6 +52,7 @@ static SSKEnvironment *sharedSSKEnvironment; @property (nonatomic) BulkProfileFetch *bulkProfileFetch; @property (nonatomic) BulkUUIDLookup *bulkUUIDLookup; @property (nonatomic) id versionedProfiles; +@property (nonatomic) ModelReadCaches *modelReadCaches; @property (nonatomic) EarlyMessageManager *earlyMessageManager; @end @@ -110,6 +111,7 @@ static SSKEnvironment *sharedSSKEnvironment; bulkProfileFetch:(BulkProfileFetch *)bulkProfileFetch bulkUUIDLookup:(BulkUUIDLookup *)bulkUUIDLookup versionedProfiles:(id)versionedProfiles + modelReadCaches:(ModelReadCaches *)modelReadCaches earlyMessageManager:(EarlyMessageManager *)earlyMessageManager { self = [super init]; @@ -162,6 +164,7 @@ static SSKEnvironment *sharedSSKEnvironment; OWSAssertDebug(bulkProfileFetch); OWSAssertDebug(versionedProfiles); OWSAssertDebug(bulkUUIDLookup); + OWSAssertDebug(modelReadCaches); OWSAssertDebug(earlyMessageManager); _contactsManager = contactsManager; @@ -210,6 +213,7 @@ static SSKEnvironment *sharedSSKEnvironment; _bulkProfileFetch = bulkProfileFetch; _versionedProfiles = versionedProfiles; _bulkUUIDLookup = bulkUUIDLookup; + _modelReadCaches = modelReadCaches; _earlyMessageManager = earlyMessageManager; return self; diff --git a/SignalServiceKit/src/TestUtils/FakeContactsManager.swift b/SignalServiceKit/src/TestUtils/FakeContactsManager.swift index cad83a621d..d22449e519 100644 --- a/SignalServiceKit/src/TestUtils/FakeContactsManager.swift +++ b/SignalServiceKit/src/TestUtils/FakeContactsManager.swift @@ -81,11 +81,6 @@ public class FakeContactsManager: NSObject, ContactsManagerProtocol { return nil } - private let _signalAccountReadCache = SignalAccountReadCache() - public var signalAccountReadCache: SignalAccountReadCache { - return _signalAccountReadCache - } - public var unknownUserLabel: String { "Unknown" } diff --git a/SignalServiceKit/src/TestUtils/MockSSKEnvironment.m b/SignalServiceKit/src/TestUtils/MockSSKEnvironment.m index e8a76d2c24..f826858937 100644 --- a/SignalServiceKit/src/TestUtils/MockSSKEnvironment.m +++ b/SignalServiceKit/src/TestUtils/MockSSKEnvironment.m @@ -108,6 +108,7 @@ NS_ASSUME_NONNULL_BEGIN BulkProfileFetch *bulkProfileFetch = [BulkProfileFetch new]; BulkUUIDLookup *bulkUUIDLookup = [BulkUUIDLookup new]; id versionedProfiles = [MockVersionedProfiles new]; + ModelReadCaches *modelReadCaches = [ModelReadCaches new]; EarlyMessageManager *earlyMessageManager = [EarlyMessageManager new]; self = [super initWithContactsManager:contactsManager @@ -156,6 +157,7 @@ NS_ASSUME_NONNULL_BEGIN bulkProfileFetch:bulkProfileFetch bulkUUIDLookup:bulkUUIDLookup versionedProfiles:versionedProfiles + modelReadCaches:modelReadCaches earlyMessageManager:earlyMessageManager]; if (!self) { diff --git a/SignalServiceKit/src/Util/ModelReadCache.swift b/SignalServiceKit/src/Util/ModelReadCache.swift index 3ec79785ce..4978cb4954 100644 --- a/SignalServiceKit/src/Util/ModelReadCache.swift +++ b/SignalServiceKit/src/Util/ModelReadCache.swift @@ -276,8 +276,8 @@ public class SignalAccountReadCache: NSObject { cache = ModelReadCache(keyBlock: { $0.recipientAddress }, - readBlock: { (address, transaction) in - return accountFinder.signalAccount(for: address, transaction: transaction) + readBlock: { (address, transaction) in + return accountFinder.signalAccount(for: address, transaction: transaction) }) } @@ -301,3 +301,53 @@ public class SignalAccountReadCache: NSObject { cache.didInsertOrUpdate(value: signalAccount, transaction: transaction) } } + +// MARK: - + +@objc +public class SignalRecipientReadCache: NSObject { + private let cache: ModelReadCache + + @objc + public override init() { + let recipientFinder = AnySignalRecipientFinder() + cache = ModelReadCache(keyBlock: { + $0.address + }, + readBlock: { (address, transaction) in + return recipientFinder.signalRecipient(for: address, transaction: transaction) + }) + } + + @objc(getSignalRecipientForAddress:transaction:) + public func getSignalRecipient(address: SignalServiceAddress, transaction: SDSAnyReadTransaction) -> SignalRecipient? { + return cache.getValue(for: address, transaction: transaction) + } + + @objc + public func getSignalRecipientWithSneakyTransaction(address: SignalServiceAddress) -> SignalRecipient? { + return cache.getValueWithSneakyTransaction(for: address) + } + + @objc(didRemoveSignalRecipient:transaction:) + public func didRemove(signalRecipient: SignalRecipient, transaction: SDSAnyWriteTransaction) { + cache.didRemove(value: signalRecipient, transaction: transaction) + } + + @objc(didInsertOrUpdateSignalRecipient:transaction:) + public func didInsertOrUpdate(signalRecipient: SignalRecipient, transaction: SDSAnyWriteTransaction) { + cache.didInsertOrUpdate(value: signalRecipient, transaction: transaction) + } +} + +// MARK: - + +@objc +public class ModelReadCaches: NSObject { + // UserProfileReadCache is only used within the profile manager. + + @objc + public let signalAccountReadCache = SignalAccountReadCache() + @objc + public let signalRecipientReadCache = SignalRecipientReadCache() +}