Commit 8127bd8b03da
tarball4 files changed+25-31
@@ -552,40 +552,22 @@ async fn fetch_reply(
552552
553553
/// under lazy-loaded members a sender may be unknown locally, and `get_member` fetches the554554
/// member list once for the room when it is555
-pub(crate) async fn profiles<'a>(555
+async fn profiles<'a>(556556
room: &Room,557557
user_ids: impl Iterator<Item = &'a OwnedUserId>,558558
) -> HashMap<OwnedUserId, Sender> {559559
let mut unique: Vec<&OwnedUserId> = user_ids.collect();560560
unique.sort();561561
unique.dedup();562
- let lookup = |users: Vec<&'a OwnedUserId>| {563
- join_all(users.into_iter().map(|user_id| async move {562
+ join_all(563
+ unique.into_iter().map(|user_id| async move {564564
Some((user_id.clone(), member_sender(room, user_id).await?))565
- }))566
- };567
- let mut found: HashMap<_, _> = lookup(unique.clone()).await.into_iter().flatten().collect();568
- let missing: Vec<_> = unique569
- .into_iter()570
- .filter(|user| !found.contains_key(*user))571
- .collect();572
- // stores have been seen with members_synced persisted over a partial roster, after which573
- // the sdk never asks /members again, so a sender it can't find marks it stale once a run574
- if !missing.is_empty() && members_rechecked(room) {575
- room.mark_members_missing();576
- found.extend(lookup(missing).await.into_iter().flatten());577
- }578
- found579
-}580
-581
-fn members_rechecked(room: &Room) -> bool {582
- static CHECKED: std::sync::LazyLock<583
- std::sync::Mutex<std::collections::HashSet<(Option<OwnedUserId>, ruma::OwnedRoomId)>>,584
- > = std::sync::LazyLock::new(Default::default);585
- CHECKED.lock().unwrap().insert((586
- room.client().user_id().map(ToOwned::to_owned),587
- room.room_id().to_owned(),588
- ))565
+ }),566
+ )567
+ .await568
+ .into_iter()569
+ .flatten()570
+ .collect()589571
}590572
591573
fn validate_limit(limit: u16) -> Result<(), Error> {@@ -1442,7 +1442,8 @@ impl Service {
14421442
}14431443
14441444
/// rows observed after their window's capture never got a profile, so one room at a time1445
- /// looks its bare senders up the way a capture does, outside the actor1445
+ /// looks its bare senders up in the member store. get_member would fetch /members for every room1446
+ /// whose members aren't synced, one after another, and that can starve sync14461447
fn schedule_profiles(&mut self, work: &mut FuturesUnordered<EngineBoxFuture<'static, Work>>) {14471448
if self.profiling {14481449
return;@@ -1502,7 +1503,18 @@ impl Service {
15021503
self.profiling = true;15031504
let users: Vec<_> = users.into_iter().collect();15041505
work.push(Box::pin(async move {1505
- let found = context::profiles(&room, users.iter()).await;1506
+ let found = futures_util::future::join_all(users.iter().map(|user_id| {1507
+ let room = &room;1508
+ async move {1509
+ crate::normalise::stored_member_sender(room, user_id)1510
+ .await1511
+ .map(|sender| (user_id.clone(), sender))1512
+ }1513
+ }))1514
+ .await1515
+ .into_iter()1516
+ .flatten()1517
+ .collect();15061518
Work::Profiles(room_id, users, found)15071519
}));15081520
}@@ -33,7 +33,7 @@ pub(crate) async fn member_sender(room: &Room, user_id: &OwnedUserId) -> Option<
3333
}3434
3535
/// what the state store already knows, without asking the server36
-async fn stored_member_sender(room: &Room, user_id: &OwnedUserId) -> Option<Sender> {36
+pub(crate) async fn stored_member_sender(room: &Room, user_id: &OwnedUserId) -> Option<Sender> {3737
let member = room.get_member_no_sync(user_id).await.ok().flatten()?;3838
Some(sender(user_id, &member))3939
}@@ -15,7 +15,7 @@ pub(crate) use image_pack::{
1515
};1616
pub(crate) use link_preview::{ROOM_PREVIEW_URLS, server_preview, url_previews_allowed};1717
pub(crate) use media::{MediaRegistration, MediaScope, MediaSourceInfo};18
-pub(crate) use member::{member_sender, member_summary};18
+pub(crate) use member::{member_sender, member_summary, stored_member_sender};1919
pub(crate) use observed::{normalise_observed, poll_question};2020
pub(crate) use room::notification_mode;2121
pub(crate) use room::{room_summaries, space_child, stored_space_order};