From b767996dba0bc4c82e2b79280b13a6c46074e539 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 4 May 2018 10:39:42 -0400 Subject: [PATCH 1/3] oOnly one system contacts fetch at a time. --- .../contacts/SystemContactsFetcher.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index b4c750fca..db835e064 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -146,6 +146,9 @@ public class SystemContactsFetcher: NSObject { public private(set) var systemContactsHaveBeenRequestedAtLeastOnce = false private var hasSetupObservation = false + private var isFetching = false + private var hasQueuedFetch = false + override init() { self.contactStoreAdapter = ContactsFrameworkContactStoreAdaptee() @@ -232,6 +235,7 @@ public class SystemContactsFetcher: NSObject { @objc public func fetchOnceIfAlreadyAuthorized() { SwiftAssertIsOnMainThread(#function) + guard authorizationStatus == .authorized else { return } @@ -269,11 +273,25 @@ public class SystemContactsFetcher: NSObject { Logger.error("background task time ran out contacts fetch completed.") }) + guard !isFetching else { + Logger.info("\(self.TAG) queuing contact fetch; contact fetch already in flight.") + hasQueuedFetch = true + return + } + isFetching = true + // Ensure completion is invoked on main thread. let completion: (Error?) -> Void = { error in DispatchMainThreadSafe({ + self.isFetching = false + completionParam?(error) backgroundTask = nil + + if self.hasQueuedFetch { + self.hasQueuedFetch = false + self.fetchOnceIfAlreadyAuthorized() + } }) } From bec5a9f428057476bedc46a75dd45ed207417bb6 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 4 May 2018 12:08:11 -0400 Subject: [PATCH 2/3] Revert "oOnly one system contacts fetch at a time." This reverts commit d84e27f5a5f953fd68dbdf1086a75ffe6aee6720. --- .../contacts/SystemContactsFetcher.swift | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index db835e064..b4c750fca 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -146,9 +146,6 @@ public class SystemContactsFetcher: NSObject { public private(set) var systemContactsHaveBeenRequestedAtLeastOnce = false private var hasSetupObservation = false - private var isFetching = false - private var hasQueuedFetch = false - override init() { self.contactStoreAdapter = ContactsFrameworkContactStoreAdaptee() @@ -235,7 +232,6 @@ public class SystemContactsFetcher: NSObject { @objc public func fetchOnceIfAlreadyAuthorized() { SwiftAssertIsOnMainThread(#function) - guard authorizationStatus == .authorized else { return } @@ -273,25 +269,11 @@ public class SystemContactsFetcher: NSObject { Logger.error("background task time ran out contacts fetch completed.") }) - guard !isFetching else { - Logger.info("\(self.TAG) queuing contact fetch; contact fetch already in flight.") - hasQueuedFetch = true - return - } - isFetching = true - // Ensure completion is invoked on main thread. let completion: (Error?) -> Void = { error in DispatchMainThreadSafe({ - self.isFetching = false - completionParam?(error) backgroundTask = nil - - if self.hasQueuedFetch { - self.hasQueuedFetch = false - self.fetchOnceIfAlreadyAuthorized() - } }) } From f9d5421edc0f04e3804f41ff908075bddbcd7be9 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 4 May 2018 12:10:03 -0400 Subject: [PATCH 3/3] Modify system contacts fetch to use serial queue. --- SignalMessaging/contacts/SystemContactsFetcher.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index b4c750fca..d11be0f6a 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -121,6 +121,9 @@ public enum ContactStoreAuthorizationStatus { public class SystemContactsFetcher: NSObject { private let TAG = "[SystemContactsFetcher]" + + private let serialQueue = DispatchQueue(label: "SystemContactsFetcherQueue") + var lastContactUpdateHash: Int? var lastDelegateNotificationDate: Date? let contactStoreAdapter: ContactsFrameworkContactStoreAdaptee @@ -280,7 +283,7 @@ public class SystemContactsFetcher: NSObject { systemContactsHaveBeenRequestedAtLeastOnce = true setupObservationIfNecessary() - DispatchQueue.global().async { + serialQueue.async { Logger.info("\(self.TAG) fetching contacts")