Move most of RelayPool away from the Main Thread

This is a large refactor that aims to improve performance by offloading
RelayPool computations into a separate actor outside the main thread.

This should reduce congestion on the main thread and thus improve UI
performance.

Also, the internal subscription callback mechanism was changed to use
AsyncStreams to prevent race conditions newly found in that area of the
code.

Changelog-Fixed: Added performance improvements to timeline scrolling
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
Daniel D’Aquino
2025-10-10 16:38:48 -07:00
parent 7c1594107f
commit 991a4a86e6
50 changed files with 602 additions and 451 deletions
@@ -55,7 +55,7 @@ class SearchHomeModel: ObservableObject {
DispatchQueue.main.async {
self.loading = true
}
let to_relays = damus_state.nostrNetwork.ourRelayDescriptors
let to_relays = await damus_state.nostrNetwork.ourRelayDescriptors
.map { $0.url }
.filter { !damus_state.relay_filters.is_filtered(timeline: .search, relay_id: $0) }
@@ -125,7 +125,7 @@ struct HashtagUnfollowButton: View {
func unfollow(_ hashtag: String) {
is_following = false
handle_unfollow(state: damus_state, unfollow: FollowRef.hashtag(hashtag))
Task { await handle_unfollow(state: damus_state, unfollow: FollowRef.hashtag(hashtag)) }
}
}
@@ -144,7 +144,7 @@ struct HashtagFollowButton: View {
func follow(_ hashtag: String) {
is_following = true
handle_follow(state: damus_state, follow: .hashtag(hashtag))
Task { await handle_follow(state: damus_state, follow: .hashtag(hashtag)) }
}
}
+2 -2
View File
@@ -69,7 +69,7 @@ struct SearchView: View {
}
appstate.mutelist_manager.set_mutelist(mutelist)
appstate.nostrNetwork.postbox.send(mutelist)
Task { await appstate.nostrNetwork.postbox.send(mutelist) }
} label: {
Text("Unmute Hashtag", comment: "Label represnting a button that the user can tap to unmute a given hashtag so they start seeing it in their feed again.")
}
@@ -104,7 +104,7 @@ struct SearchView: View {
}
appstate.mutelist_manager.set_mutelist(mutelist)
appstate.nostrNetwork.postbox.send(mutelist)
Task { await appstate.nostrNetwork.postbox.send(mutelist) }
}
var described_search: DescribedSearch {