diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 58d0b0abc..58f4fcba3 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2575,6 +2575,11 @@ nonisolated class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { } nonisolated(unsafe) var underlyingMaxMediaUploadSize: Result! nonisolated(unsafe) var maxMediaUploadSizeClosure: (() async -> Result)? + var isSearchBackfillRunning: Bool { + get { return underlyingIsSearchBackfillRunning } + set(value) { underlyingIsSearchBackfillRunning = value } + } + nonisolated(unsafe) var underlyingIsSearchBackfillRunning: Bool! var liveLocationOwnInfoUpdatesPublisher: AnyPublisher { get { return underlyingLiveLocationOwnInfoUpdatesPublisher } set(value) { underlyingLiveLocationOwnInfoUpdatesPublisher = value } @@ -2699,6 +2704,54 @@ nonisolated class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { pauseServicesCallsCountLock.withLock { pauseServicesUnderlyingCallsCount += 1 } await pauseServicesClosure?() } + //MARK: - startSearchBackfill + + private let startSearchBackfillStrategyCallsCountLock = NSLock() + private nonisolated(unsafe) var startSearchBackfillStrategyUnderlyingCallsCount = 0 + var startSearchBackfillStrategyCallsCount: Int { + get { startSearchBackfillStrategyCallsCountLock.withLock { startSearchBackfillStrategyUnderlyingCallsCount } } + set { startSearchBackfillStrategyCallsCountLock.withLock { startSearchBackfillStrategyUnderlyingCallsCount = newValue } } + } + var startSearchBackfillStrategyCalled: Bool { + return startSearchBackfillStrategyCallsCount > 0 + } + private let startSearchBackfillStrategyReceivedStrategyLock = NSLock() + private nonisolated(unsafe) var startSearchBackfillStrategyUnderlyingReceivedStrategy: SearchBackfillStrategy? + var startSearchBackfillStrategyReceivedStrategy: SearchBackfillStrategy? { + get { startSearchBackfillStrategyReceivedStrategyLock.withLock { startSearchBackfillStrategyUnderlyingReceivedStrategy } } + set { startSearchBackfillStrategyReceivedStrategyLock.withLock { startSearchBackfillStrategyUnderlyingReceivedStrategy = newValue } } + } + private let startSearchBackfillStrategyReceivedInvocationsLock = NSLock() + private nonisolated(unsafe) var startSearchBackfillStrategyUnderlyingReceivedInvocations: [SearchBackfillStrategy] = [] + var startSearchBackfillStrategyReceivedInvocations: [SearchBackfillStrategy] { + get { startSearchBackfillStrategyReceivedInvocationsLock.withLock { startSearchBackfillStrategyUnderlyingReceivedInvocations } } + set { startSearchBackfillStrategyReceivedInvocationsLock.withLock { startSearchBackfillStrategyUnderlyingReceivedInvocations = newValue } } + } + nonisolated(unsafe) var startSearchBackfillStrategyClosure: ((SearchBackfillStrategy) -> Void)? + + func startSearchBackfill(strategy: SearchBackfillStrategy) { + startSearchBackfillStrategyCallsCountLock.withLock { startSearchBackfillStrategyUnderlyingCallsCount += 1 } + startSearchBackfillStrategyReceivedStrategy = strategy + startSearchBackfillStrategyReceivedInvocationsLock.withLock { startSearchBackfillStrategyUnderlyingReceivedInvocations.append(strategy) } + startSearchBackfillStrategyClosure?(strategy) + } + //MARK: - stopSearchBackfill + + private let stopSearchBackfillCallsCountLock = NSLock() + private nonisolated(unsafe) var stopSearchBackfillUnderlyingCallsCount = 0 + var stopSearchBackfillCallsCount: Int { + get { stopSearchBackfillCallsCountLock.withLock { stopSearchBackfillUnderlyingCallsCount } } + set { stopSearchBackfillCallsCountLock.withLock { stopSearchBackfillUnderlyingCallsCount = newValue } } + } + var stopSearchBackfillCalled: Bool { + return stopSearchBackfillCallsCount > 0 + } + nonisolated(unsafe) var stopSearchBackfillClosure: (() -> Void)? + + func stopSearchBackfill() { + stopSearchBackfillCallsCountLock.withLock { stopSearchBackfillUnderlyingCallsCount += 1 } + stopSearchBackfillClosure?() + } //MARK: - expireSyncSessions private let expireSyncSessionsCallsCountLock = NSLock() diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 5b6c22b9a..55c50ed0b 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -56,6 +56,8 @@ class ClientProxy: ClientProxyProtocol { private var delegateHandle: TaskHandle? + private var searchBackfillTaskHandle: TaskHandle? + // These following summary providers both operate on the same allRooms() list but // can apply their own filtering and pagination private(set) var roomSummaryProvider: RoomSummaryProviderProtocol @@ -473,6 +475,25 @@ class ClientProxy: ClientProxyProtocol { await transitionServices(to: .suspended).value } + func startSearchBackfill(strategy: SearchBackfillStrategy) { + if strategy == .foreground, isSearchBackfillRunning { + return + } + + MXLog.info("Starting search backfill with strategy: \(strategy)") + searchBackfillTaskHandle?.cancel() + searchBackfillTaskHandle = client.runSearchBackfill(strategy: strategy) + } + + func stopSearchBackfill() { + searchBackfillTaskHandle?.cancel() + searchBackfillTaskHandle = nil + } + + var isSearchBackfillRunning: Bool { + searchBackfillTaskHandle?.isFinished() == false + } + func expireSyncSessions() async { await syncService.expireSessions() } @@ -1188,6 +1209,8 @@ class ClientProxy: ClientProxyProtocol { case .suspended: updateHomeserverReachability() + stopSearchBackfill() + MXLog.info("Stopping sync") await syncService.stop() MXLog.info("Sync stopped") diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index bc614825c..09a57fd76 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -187,6 +187,12 @@ protocol ClientProxyProtocol: AnyObject { func pauseServices() async + func startSearchBackfill(strategy: SearchBackfillStrategy) + + func stopSearchBackfill() + + var isSearchBackfillRunning: Bool { get } + func expireSyncSessions() async func accountURL(action: AccountManagementAction) async -> URL?