Skip to content

Commit 17de97e

Browse files
committed
refactor(sdk): Fetch member data concurrently
Creating a `RoomMember` takes a lot of store queries, and previously all of them were done sequentially. I've tried to make this process run as much in parallel as I can.
1 parent b4ebc8b commit 17de97e

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

crates/matrix-sdk-base/src/room/members.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::{
1919
};
2020

2121
use bitflags::bitflags;
22+
use futures_util::future;
2223
use ruma::{
2324
Int, MxcUri, OwnedUserId, UserId,
2425
events::{
@@ -35,7 +36,7 @@ use tracing::debug;
3536

3637
use super::Room;
3738
use crate::{
38-
MinimalRoomMemberEvent,
39+
MinimalRoomMemberEvent, StoreError,
3940
deserialized_responses::{DisplayName, MemberEvent},
4041
store::{Result as StoreResult, StateStoreExt, ambiguity_map::is_display_name_ambiguous},
4142
};
@@ -140,17 +141,26 @@ impl Room {
140141
///
141142
/// Async because it can read from storage.
142143
pub async fn get_member(&self, user_id: &UserId) -> StoreResult<Option<RoomMember>> {
143-
let Some(raw_event) = self.store.get_member_event(self.room_id(), user_id).await? else {
144-
debug!(%user_id, "Member event not found in state store");
145-
return Ok(None);
144+
let event = async {
145+
let Some(raw_event) = self.store.get_member_event(self.room_id(), user_id).await?
146+
else {
147+
debug!(%user_id, "Member event not found in state store");
148+
return Ok(None);
149+
};
150+
151+
Ok(Some(raw_event.deserialize()?))
152+
};
153+
let presence = async {
154+
let raw_event = self.store.get_presence_event(user_id).await?;
155+
Ok::<Option<PresenceEvent>, StoreError>(raw_event.and_then(|e| e.deserialize().ok()))
146156
};
147157

148-
let event = raw_event.deserialize()?;
149-
150-
let presence =
151-
self.store.get_presence_event(user_id).await?.and_then(|e| e.deserialize().ok());
158+
let profile = async { self.store.get_profile(self.room_id(), user_id).await };
152159

153-
let profile = self.store.get_profile(self.room_id(), user_id).await?;
160+
let (Some(event), presence, profile) = future::try_join3(event, presence, profile).await?
161+
else {
162+
return Ok(None);
163+
};
154164

155165
let display_names = [event.display_name()];
156166
let room_info = self.member_room_info(&display_names).await?;
@@ -166,23 +176,26 @@ impl Room {
166176
display_names: &'a [DisplayName],
167177
) -> StoreResult<MemberRoomInfo<'a>> {
168178
let max_power_level = self.max_power_level();
169-
let power_levels = self.power_levels_or_default().await;
179+
let power_levels = self.power_levels_or_default();
170180

171181
let users_display_names =
172-
self.store.get_users_with_display_names(self.room_id(), display_names).await?;
182+
self.store.get_users_with_display_names(self.room_id(), display_names);
173183

174-
let ignored_users = self
175-
.store
176-
.get_account_data_event_static::<IgnoredUserListEventContent>()
177-
.await?
184+
let raw_ignored_users =
185+
self.store.get_account_data_event_static::<IgnoredUserListEventContent>();
186+
187+
let (power_levels, users_display_names, raw_ignored_users) =
188+
future::join3(power_levels, users_display_names, raw_ignored_users).await;
189+
190+
let ignored_users = raw_ignored_users?
178191
.map(|c| c.deserialize())
179192
.transpose()?
180193
.map(|e| e.content.ignored_users.into_keys().collect());
181194

182195
Ok(MemberRoomInfo {
183196
power_levels: power_levels.into(),
184197
max_power_level,
185-
users_display_names,
198+
users_display_names: users_display_names?,
186199
ignored_users,
187200
})
188201
}

0 commit comments

Comments
 (0)