From de4dfbb2cde75859b632ab018e84725a0fe850f7 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 7 Sep 2023 18:41:33 +0100 Subject: [PATCH 1/2] Stop the sync service constantly attempting to restart on auth error. Additionally removes a retain cycle that was preventing the client from being released. --- .../FlowCoordinators/UserSessionFlowCoordinator.swift | 11 ++++++----- ElementX/Sources/Services/Client/ClientProxy.swift | 9 +++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift index 89d68a7a69..dce5ec2cf6 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift @@ -73,14 +73,15 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { setupStateMachine() - roomFlowCoordinator.actions.sink { action in + roomFlowCoordinator.actions.sink { [weak self] action in + guard let self else { return } switch action { case .presentedRoom(let roomID): - self.analytics.signpost.beginRoomFlow(roomID) - self.stateMachine.processEvent(.selectRoom(roomID: roomID)) + analytics.signpost.beginRoomFlow(roomID) + stateMachine.processEvent(.selectRoom(roomID: roomID)) case .dismissedRoom: - self.stateMachine.processEvent(.deselectRoom) - self.analytics.signpost.endRoomFlow() + stateMachine.processEvent(.deselectRoom) + analytics.signpost.endRoomFlow() } } .store(in: &cancellables) diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 34cc03d2a2..31a0ec831a 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -54,6 +54,11 @@ class ClientProxy: ClientProxyProtocol { private var cancellables = Set() private var visibleRoomsListProxyStateObservationToken: AnyCancellable? + /// Will be `true` whilst the app cleans up and forces a logout. Prevents the sync service from restarting + /// before the client is released which ends up running in a loop. This is a workaround until the sync service + /// can tell us *what* error occurred so we can handle restarts more gracefully. + private var hasEncounteredAuthError = false + deinit { client.setDelegate(delegate: nil) stopSync() @@ -79,6 +84,7 @@ class ClientProxy: ClientProxyProtocol { backgroundTaskService: backgroundTaskService) client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in + self?.hasEncounteredAuthError = true self?.callbacks.send(.receivedAuthError(isSoftLogout: isSoftLogout)) } tokenRefreshCallback: { [weak self] in self?.callbacks.send(.updateRestorationToken) @@ -125,6 +131,8 @@ class ClientProxy: ClientProxyProtocol { } func startSync() { + guard !hasEncounteredAuthError else { return } + MXLog.info("Starting sync") Task { @@ -372,6 +380,7 @@ class ClientProxy: ClientProxyProtocol { MXLog.error("Failed restarting the sync service with error: \(error)") } + guard !hasEncounteredAuthError else { return } await self.syncService?.start() } } From c6670176f7e122d90a018b0e9cc4cfaed9670243 Mon Sep 17 00:00:00 2001 From: Doug Date: Fri, 8 Sep 2023 10:24:40 +0100 Subject: [PATCH 2/2] Remove restartSync. The SDK has changed a lot, we no longer need to stop and start the sync loop. --- .../Sources/Services/Client/ClientProxy.swift | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 31a0ec831a..44bfd21653 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -131,7 +131,10 @@ class ClientProxy: ClientProxyProtocol { } func startSync() { - guard !hasEncounteredAuthError else { return } + guard !hasEncounteredAuthError else { + MXLog.warning("Ignoring request, this client has an unknown token.") + return + } MXLog.info("Starting sync") @@ -368,22 +371,6 @@ class ClientProxy: ClientProxyProtocol { } // MARK: Private - - private func restartSync(delay: Duration = .zero) { - Task { - try await Task.sleep(for: delay) - - do { - MXLog.info("Restarting the sync service.") - try await self.syncService?.stop() - } catch { - MXLog.error("Failed restarting the sync service with error: \(error)") - } - - guard !hasEncounteredAuthError else { return } - await self.syncService?.start() - } - } private func loadUserAvatarURLFromCache() { loadCachedAvatarURLTask = Task { @@ -451,7 +438,7 @@ class ClientProxy: ClientProxyProtocol { case .running, .terminated, .idle: break case .error: - restartSync() + startSync() } }) }