Replace old visible rooms range with subscriptions in the room list. (#3014)

* Add a SubscriptionTracker actor to RoomProxy.

* Request subscriptions when scrolling rooms.

* Stop unsubscribing in preparation for Simplified Sliding Sync.
This commit is contained in:
Doug
2024-07-08 14:32:13 +01:00
committed by GitHub
parent bf9e1d614f
commit a1329d9d54
6 changed files with 31 additions and 58 deletions
@@ -680,8 +680,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
navigationStackCoordinator.setRootCoordinator(nil, animated: false) navigationStackCoordinator.setRootCoordinator(nil, animated: false)
} }
roomProxy?.unsubscribeFromUpdates()
timelineController = nil timelineController = nil
actionsSubject.send(.finished) actionsSubject.send(.finished)
@@ -8259,41 +8259,6 @@ class RoomProxyMock: RoomProxyProtocol {
subscribeForUpdatesCallsCount += 1 subscribeForUpdatesCallsCount += 1
await subscribeForUpdatesClosure?() await subscribeForUpdatesClosure?()
} }
//MARK: - unsubscribeFromUpdates
var unsubscribeFromUpdatesUnderlyingCallsCount = 0
var unsubscribeFromUpdatesCallsCount: Int {
get {
if Thread.isMainThread {
return unsubscribeFromUpdatesUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = unsubscribeFromUpdatesUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
unsubscribeFromUpdatesUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
unsubscribeFromUpdatesUnderlyingCallsCount = newValue
}
}
}
}
var unsubscribeFromUpdatesCalled: Bool {
return unsubscribeFromUpdatesCallsCount > 0
}
var unsubscribeFromUpdatesClosure: (() -> Void)?
func unsubscribeFromUpdates() {
unsubscribeFromUpdatesCallsCount += 1
unsubscribeFromUpdatesClosure?()
}
//MARK: - timelineFocusedOnEvent //MARK: - timelineFocusedOnEvent
var timelineFocusedOnEventEventIDNumberOfEventsUnderlyingCallsCount = 0 var timelineFocusedOnEventEventIDNumberOfEventsUnderlyingCallsCount = 0
@@ -46,7 +46,15 @@ enum ClientProxyError: Error {
} }
enum SlidingSyncConstants { enum SlidingSyncConstants {
static let defaultTimelineLimit: UInt = 20 static let defaultTimelineLimit: UInt32 = 20
static let maximumVisibleRangeSize = 30
static let defaultRequiredState = [
RequiredState(key: "m.room.name", value: ""),
RequiredState(key: "m.room.topic", value: ""),
RequiredState(key: "m.room.avatar", value: ""),
RequiredState(key: "m.room.canonical_alias", value: ""),
RequiredState(key: "m.room.join_rules", value: "")
]
} }
/// This struct represents the configuration that we are using to register the application through Pusher to Sygnal /// This struct represents the configuration that we are using to register the application through Pusher to Sygnal
+2 -17
View File
@@ -21,8 +21,6 @@ import UIKit
import MatrixRustSDK import MatrixRustSDK
class RoomProxy: RoomProxyProtocol { class RoomProxy: RoomProxyProtocol {
private static var subscriptionCountPerRoom: [String: Int] = [:]
private let roomListItem: RoomListItemProtocol private let roomListItem: RoomListItemProtocol
private let room: RoomProtocol private let room: RoomProtocol
let timeline: TimelineProxyProtocol let timeline: TimelineProxyProtocol
@@ -145,15 +143,10 @@ class RoomProxy: RoomProxyProtocol {
} }
subscribedForUpdates = true subscribedForUpdates = true
let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.name", value: ""), let settings = RoomSubscription(requiredState: SlidingSyncConstants.defaultRequiredState,
RequiredState(key: "m.room.topic", value: ""), timelineLimit: SlidingSyncConstants.defaultTimelineLimit,
RequiredState(key: "m.room.avatar", value: ""),
RequiredState(key: "m.room.canonical_alias", value: ""),
RequiredState(key: "m.room.join_rules", value: "")],
timelineLimit: UInt32(SlidingSyncConstants.defaultTimelineLimit),
includeHeroes: false) // We don't need heroes here as they're already included in the `all_rooms` list includeHeroes: false) // We don't need heroes here as they're already included in the `all_rooms` list
roomListItem.subscribe(settings: settings) roomListItem.subscribe(settings: settings)
Self.subscriptionCountPerRoom[roomListItem.id()] = (Self.subscriptionCountPerRoom[roomListItem.id()] ?? 0) + 1
await timeline.subscribeForUpdates() await timeline.subscribeForUpdates()
@@ -162,14 +155,6 @@ class RoomProxy: RoomProxyProtocol {
subscribeToTypingNotifications() subscribeToTypingNotifications()
} }
func unsubscribeFromUpdates() {
Self.subscriptionCountPerRoom[roomListItem.id()] = max(0, (Self.subscriptionCountPerRoom[roomListItem.id()] ?? 0) - 1)
if Self.subscriptionCountPerRoom[roomListItem.id()] ?? 0 <= 0 {
roomListItem.unsubscribe()
}
}
func timelineFocusedOnEvent(eventID: String, numberOfEvents: UInt16) async -> Result<TimelineProxyProtocol, RoomProxyError> { func timelineFocusedOnEvent(eventID: String, numberOfEvents: UInt16) async -> Result<TimelineProxyProtocol, RoomProxyError> {
do { do {
let timeline = try await room.timelineFocusedOnEvent(eventId: eventID, numContextEvents: numberOfEvents, internalIdPrefix: UUID().uuidString) let timeline = try await room.timelineFocusedOnEvent(eventId: eventID, numContextEvents: numberOfEvents, internalIdPrefix: UUID().uuidString)
@@ -66,8 +66,6 @@ protocol RoomProxyProtocol {
func subscribeForUpdates() async func subscribeForUpdates() async
func unsubscribeFromUpdates()
func timelineFocusedOnEvent(eventID: String, numberOfEvents: UInt16) async -> Result<TimelineProxyProtocol, RoomProxyError> func timelineFocusedOnEvent(eventID: String, numberOfEvents: UInt16) async -> Result<TimelineProxyProtocol, RoomProxyError>
func redact(_ eventID: String) async -> Result<Void, RoomProxyError> func redact(_ eventID: String) async -> Result<Void, RoomProxyError>
@@ -58,7 +58,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
/// Build a new summary provider with the given parameters /// Build a new summary provider with the given parameters
/// - Parameters: /// - Parameters:
/// - shouldUpdateVisibleRange: whether this summary provider should foward visible ranges /// - shouldUpdateVisibleRange: whether this summary provider should forward visible ranges
/// to the room list service through the `applyInput(input: .viewport(ranges` api. Only useful for /// to the room list service through the `applyInput(input: .viewport(ranges` api. Only useful for
/// lists that need to update the visible range on Sliding Sync /// lists that need to update the visible range on Sliding Sync
init(roomListService: RoomListServiceProtocol, init(roomListService: RoomListServiceProtocol,
@@ -124,6 +124,25 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
guard shouldUpdateVisibleRange else { guard shouldUpdateVisibleRange else {
return return
} }
// The scroll view content size based visible range calculations might create large ranges
// This is just a safety check to not overload the backend
var range = range
if range.upperBound - range.lowerBound > SlidingSyncConstants.maximumVisibleRangeSize {
let upperBound = range.lowerBound + SlidingSyncConstants.maximumVisibleRangeSize
range = range.lowerBound..<upperBound
}
MXLog.info("\(name): Requesting subscriptions for visible range: \(range)")
for index in range {
guard index < rooms.count else { return }
// Note, we must use the item received by the diff. Asking the roomListService to get
// a new item instance will result in /sync being called when already subscribed.
rooms[index].roomListItem.subscribe(settings: .init(requiredState: SlidingSyncConstants.defaultRequiredState,
timelineLimit: SlidingSyncConstants.defaultTimelineLimit,
includeHeroes: false))
}
} }
func setFilter(_ filter: RoomSummaryProviderFilter) { func setFilter(_ filter: RoomSummaryProviderFilter) {