diff --git a/SignalServiceKit/Dependencies/DependenciesBridge.swift b/SignalServiceKit/Dependencies/DependenciesBridge.swift index f8696f2e4c..8d4b463b9e 100644 --- a/SignalServiceKit/Dependencies/DependenciesBridge.swift +++ b/SignalServiceKit/Dependencies/DependenciesBridge.swift @@ -553,6 +553,7 @@ public class DependenciesBridge { tsAccountManager: tsAccountManager ) + self.socketManager = SocketManagerImpl(appExpiry: appExpiry, db: db) self.preKeyManager = PreKeyManagerImpl( dateProvider: dateProvider, db: db, @@ -561,8 +562,8 @@ public class DependenciesBridge { messageProcessor: PreKey.Wrappers.MessageProcessor(messageProcessor: messageProcessor), protocolStoreManager: signalProtocolStoreManager, serviceClient: accountServiceClient, + socketManager: self.socketManager, tsAccountManager: tsAccountManager - ) self.learnMyOwnPniManager = LearnMyOwnPniManagerImpl( @@ -697,7 +698,6 @@ public class DependenciesBridge { tsAccountManager: tsAccountManager ) - self.socketManager = SocketManagerImpl(appExpiry: appExpiry, db: db) self.externalPendingIDEALDonationStore = ExternalPendingIDEALDonationStoreImpl(keyStoreFactory: keyValueStoreFactory) // TODO: Move this into ProfileFetcherJob. diff --git a/SignalServiceKit/src/Account/PreKeys/PreKeyTaskManager.swift b/SignalServiceKit/src/Account/PreKeys/PreKeyTaskManager.swift index 9c864a3ca3..5f6bb7e393 100644 --- a/SignalServiceKit/src/Account/PreKeys/PreKeyTaskManager.swift +++ b/SignalServiceKit/src/Account/PreKeys/PreKeyTaskManager.swift @@ -146,7 +146,7 @@ internal struct PreKeyTaskManager { ) async throws { PreKey.logger.info("[\(identity)] Refresh [\(targets)]") try Task.checkCancellation() - try await waitForMessageProcessing() + try await waitForMessageProcessing(identity: identity) try Task.checkCancellation() let unfilteredTargets = targets @@ -191,7 +191,7 @@ internal struct PreKeyTaskManager { ) async throws { PreKey.logger.info("[\(identity)] Rotate [\(targets)]") try Task.checkCancellation() - try await waitForMessageProcessing() + try await waitForMessageProcessing(identity: identity) try Task.checkCancellation() let bundle = try await db.awaitableWrite { tx in let identityKeyPair = try self.requireIdentityKeyPair(for: identity, tx: tx) @@ -236,7 +236,7 @@ internal struct PreKeyTaskManager { ) async throws { PreKey.logger.info("[PNI] Create or Rotate PNI [\(targets)]") try Task.checkCancellation() - try await waitForMessageProcessing() + try await waitForMessageProcessing(identity: .pni) try Task.checkCancellation() let bundle = try await db.awaitableWrite { tx in let identityKeyPair = self.getOrCreateIdentityKeyPair(identity: .pni, tx: tx) @@ -435,9 +435,18 @@ internal struct PreKeyTaskManager { private class MessageProcessingTimeoutError: Swift.Error {} /// Waits (potentially forever) for message processing, pausing every couple of seconds if not finished to check for cancellation. - private func waitForMessageProcessing() async throws { + private func waitForMessageProcessing(identity: OWSIdentity) async throws { try Task.checkCancellation() + switch identity { + case .aci: + // We can't change our ACI via a message, so there's no need to wait. + return + case .pni: + // Our PNI might change via a change number message, so wait. + break + } + do { try await messageProcessor.waitForFetchingAndProcessing().asPromise() .timeout(seconds: 3, timeoutErrorBlock: { MessageProcessingTimeoutError() }) @@ -445,7 +454,7 @@ internal struct PreKeyTaskManager { } catch let error { if error is MessageProcessingTimeoutError { // try again so we get the chance to check for cancellation. - try await self.waitForMessageProcessing() + try await self.waitForMessageProcessing(identity: identity) return } throw SSKUnretryableError.messageProcessingFailed diff --git a/SignalServiceKit/src/Account/PreKeys/PrekeyManagerImpl.swift b/SignalServiceKit/src/Account/PreKeys/PrekeyManagerImpl.swift index 5d09158389..2b3b7cf016 100644 --- a/SignalServiceKit/src/Account/PreKeys/PrekeyManagerImpl.swift +++ b/SignalServiceKit/src/Account/PreKeys/PrekeyManagerImpl.swift @@ -29,6 +29,7 @@ public class PreKeyManagerImpl: PreKeyManager { private let db: DB private let identityManager: PreKey.Shims.IdentityManager private let protocolStoreManager: SignalProtocolStoreManager + private let socketManager: any SocketManager private let taskManager: PreKeyTaskManager @@ -40,11 +41,13 @@ public class PreKeyManagerImpl: PreKeyManager { messageProcessor: PreKey.Shims.MessageProcessor, protocolStoreManager: SignalProtocolStoreManager, serviceClient: AccountServiceClient, + socketManager: any SocketManager, tsAccountManager: TSAccountManager ) { self.db = db self.identityManager = identityManager self.protocolStoreManager = protocolStoreManager + self.socketManager = socketManager self.taskManager = PreKeyTaskManager( dateProvider: dateProvider, @@ -132,8 +135,9 @@ public class PreKeyManagerImpl: PreKeyManager { } let shouldPerformPniOp = hasPniIdentityKey(tx: tx) - Task { [weak self, taskManager, targets] in + Task { [weak self, socketManager, taskManager, targets] in let task = await Self.taskQueue.enqueue { + try await socketManager.waitForSocketToOpen(webSocketType: .identified) try Task.checkCancellation() try await taskManager.refresh(identity: .aci, targets: targets, auth: .implicit()) if shouldPerformPniOp { @@ -215,7 +219,8 @@ public class PreKeyManagerImpl: PreKeyManager { let targets: PreKey.Target = [.signedPreKey, .lastResortPqPreKey] let shouldPerformPniOp = db.read(block: hasPniIdentityKey(tx:)) - return await Self.taskQueue.enqueue { [weak self, taskManager, targets] in + return await Self.taskQueue.enqueue { [weak self, socketManager, taskManager, targets] in + try await socketManager.waitForSocketToOpen(webSocketType: .identified) try Task.checkCancellation() try await taskManager.rotate(identity: .aci, targets: targets, auth: .implicit()) if shouldPerformPniOp {