Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-05-30 - [Performance] Parallelize initial space sync fetching
**Learning:** In space service synchronization, iterating over space rooms and asynchronously fetching avatar for each space using `await` sequentially causes blocking for I/O bounds when joining multiple spaces, potentially leading to performance bottlenecks during initial startup.
**Action:** Use `futures_util::future::join_all` to concurrently fetch avatar and information for all initial spaces, reducing latency and time spent initializing spaces list. Parallelizing space sync fetching and queuing preserves order while drastically reducing blocking.
31 changes: 23 additions & 8 deletions src/space_service_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,11 @@ pub async fn space_service_loop(client: Client) -> anyhow::Result<()> {

// Get the set of top-level (root) spaces that the user has joined.
let (initial_spaces, mut spaces_diff_stream) = space_service.subscribe_to_top_level_joined_spaces().await;
for space in &initial_spaces {
add_new_space(space, &client).await;
let jsi_futures = futures_util::future::join_all(
initial_spaces.iter().map(|space| get_joined_space_info(space, &client))
).await;
for jsi in jsi_futures {
enqueue_spaces_list_update(SpacesListUpdate::AddJoinedSpace(jsi));
}
let mut all_joined_spaces: Vector<SpaceRoom> = initial_spaces;
if LOG_SPACE_SERVICE_DIFFS { log!("space_service: initial set: {all_joined_spaces:?}"); }
Expand Down Expand Up @@ -224,8 +227,13 @@ pub async fn space_service_loop(client: Client) -> anyhow::Result<()> {
match diff {
VectorDiff::Append { values: new_spaces } => {
if LOG_SPACE_SERVICE_DIFFS { log!("space_service: diff Append {}", new_spaces.len()); }
let jsi_futures = futures_util::future::join_all(
new_spaces.iter().map(|space| get_joined_space_info(space, &client))
).await;
for jsi in jsi_futures {
enqueue_spaces_list_update(SpacesListUpdate::AddJoinedSpace(jsi));
}
for new_space in new_spaces {
add_new_space(&new_space, &client).await;
all_joined_spaces.push_back(new_space);
}
}
Expand Down Expand Up @@ -315,8 +323,11 @@ pub async fn space_service_loop(client: Client) -> anyhow::Result<()> {
remove_space(&space);
}
enqueue_spaces_list_update(SpacesListUpdate::ClearSpaces);
for new_space in &new_spaces {
add_new_space(new_space, &client).await;
let jsi_futures = futures_util::future::join_all(
new_spaces.iter().map(|space| get_joined_space_info(space, &client))
).await;
for jsi in jsi_futures {
enqueue_spaces_list_update(SpacesListUpdate::AddJoinedSpace(jsi));
}
all_joined_spaces = new_spaces;
}
Expand All @@ -335,6 +346,11 @@ pub async fn space_service_loop(client: Client) -> anyhow::Result<()> {


async fn add_new_space(space: &SpaceRoom, client: &Client) {
let jsi = get_joined_space_info(space, client).await;
enqueue_spaces_list_update(SpacesListUpdate::AddJoinedSpace(jsi));
}

async fn get_joined_space_info(space: &SpaceRoom, client: &Client) -> JoinedSpaceInfo {
let space_avatar_opt = if let Some(url) = &space.avatar_url {
fetch_space_avatar(url.clone(), client)
.await
Expand All @@ -345,7 +361,7 @@ async fn add_new_space(space: &SpaceRoom, client: &Client) {
|| utils::avatar_from_room_name(Some(&space.display_name))
);

let jsi = JoinedSpaceInfo {
JoinedSpaceInfo {
space_name_id: RoomNameId::new(
matrix_sdk::RoomDisplayName::Named(space.display_name.clone()),
space.room_id.clone(),
Expand All @@ -358,8 +374,7 @@ async fn add_new_space(space: &SpaceRoom, client: &Client) {
world_readable: space.world_readable,
guest_can_join: space.guest_can_join,
children_count: space.children_count,
};
enqueue_spaces_list_update(SpacesListUpdate::AddJoinedSpace(jsi));
}
}


Expand Down
Loading