fix profile updates reusing old membership content + small parallelise + remove unnecessary Result

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-12-07 00:46:22 -05:00
parent 35e9d9b02e
commit c070edc189
3 changed files with 89 additions and 76 deletions

View file

@ -213,8 +213,8 @@ pub(super) async fn deactivate(&self, no_leave_rooms: bool, user_id: String) ->
.await; .await;
full_user_deactivate(self.services, &user_id, &all_joined_rooms).await?; full_user_deactivate(self.services, &user_id, &all_joined_rooms).await?;
update_displayname(self.services, &user_id, None, &all_joined_rooms).await?; update_displayname(self.services, &user_id, None, &all_joined_rooms).await;
update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms).await?; update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms).await;
leave_all_rooms(self.services, &user_id).await; leave_all_rooms(self.services, &user_id).await;
} }
@ -327,12 +327,8 @@ pub(super) async fn deactivate_all(&self, no_leave_rooms: bool, force: bool) ->
.await; .await;
full_user_deactivate(self.services, &user_id, &all_joined_rooms).await?; full_user_deactivate(self.services, &user_id, &all_joined_rooms).await?;
update_displayname(self.services, &user_id, None, &all_joined_rooms) update_displayname(self.services, &user_id, None, &all_joined_rooms).await;
.await update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms).await;
.ok();
update_avatar_url(self.services, &user_id, None, None, &all_joined_rooms)
.await
.ok();
leave_all_rooms(self.services, &user_id).await; leave_all_rooms(self.services, &user_id).await;
} }
}, },

View file

@ -648,8 +648,8 @@ pub(crate) async fn deactivate_route(
.collect() .collect()
.await; .await;
super::update_displayname(&services, sender_user, None, &all_joined_rooms).await?; super::update_displayname(&services, sender_user, None, &all_joined_rooms).await;
super::update_avatar_url(&services, sender_user, None, None, &all_joined_rooms).await?; super::update_avatar_url(&services, sender_user, None, None, &all_joined_rooms).await;
full_user_deactivate(&services, sender_user, &all_joined_rooms).await?; full_user_deactivate(&services, sender_user, &all_joined_rooms).await?;
@ -744,9 +744,9 @@ pub(crate) async fn check_registration_token_validity(
pub async fn full_user_deactivate( pub async fn full_user_deactivate(
services: &Services, user_id: &UserId, all_joined_rooms: &[OwnedRoomId], services: &Services, user_id: &UserId, all_joined_rooms: &[OwnedRoomId],
) -> Result<()> { ) -> Result<()> {
services.users.deactivate_account(user_id).await?; services.users.deactivate_account(user_id).await.ok();
super::update_displayname(services, user_id, None, all_joined_rooms).await?; super::update_displayname(services, user_id, None, all_joined_rooms).await;
super::update_avatar_url(services, user_id, None, None, all_joined_rooms).await?; super::update_avatar_url(services, user_id, None, None, all_joined_rooms).await;
services services
.users .users

View file

@ -1,10 +1,12 @@
use std::collections::BTreeMap;
use axum::extract::State; use axum::extract::State;
use conduit::{ use conduit::{
pdu::PduBuilder, pdu::PduBuilder,
utils::{stream::TryIgnore, IterStream}, utils::{stream::TryIgnore, IterStream},
warn, Err, Error, Result, warn, Err, Error, Result,
}; };
use futures::{StreamExt, TryStreamExt}; use futures::{future::join3, StreamExt, TryStreamExt};
use ruma::{ use ruma::{
api::{ api::{
client::{ client::{
@ -13,7 +15,7 @@ use ruma::{
}, },
federation, federation,
}, },
events::{room::member::RoomMemberEventContent, StateEventType}, events::room::member::{MembershipState, RoomMemberEventContent},
presence::PresenceState, presence::PresenceState,
OwnedMxcUri, OwnedRoomId, UserId, OwnedMxcUri, OwnedRoomId, UserId,
}; };
@ -43,7 +45,7 @@ pub(crate) async fn set_displayname_route(
.collect() .collect()
.await; .await;
update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms).await?; update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms).await;
if services.globals.allow_local_presence() { if services.globals.allow_local_presence() {
// Presence update // Presence update
@ -138,7 +140,7 @@ pub(crate) async fn set_avatar_url_route(
body.blurhash.clone(), body.blurhash.clone(),
&all_joined_rooms, &all_joined_rooms,
) )
.await?; .await;
if services.globals.allow_local_presence() { if services.globals.allow_local_presence() {
// Presence update // Presence update
@ -294,79 +296,43 @@ pub(crate) async fn get_profile_route(
pub async fn update_displayname( pub async fn update_displayname(
services: &Services, user_id: &UserId, displayname: Option<String>, all_joined_rooms: &[OwnedRoomId], services: &Services, user_id: &UserId, displayname: Option<String>, all_joined_rooms: &[OwnedRoomId],
) -> Result<()> { ) {
let current_display_name = services.users.displayname(user_id).await.ok(); let (current_avatar_url, current_blurhash, current_displayname) = join3(
services.users.avatar_url(user_id),
services.users.blurhash(user_id),
services.users.displayname(user_id),
)
.await;
if displayname == current_display_name { let current_avatar_url = current_avatar_url.ok();
return Ok(()); let current_blurhash = current_blurhash.ok();
let current_displayname = current_displayname.ok();
if displayname == current_displayname {
return;
} }
services.users.set_displayname(user_id, displayname.clone()); services.users.set_displayname(user_id, displayname.clone());
// Send a new join membership event into all joined rooms // Send a new join membership event into all joined rooms
let mut joined_rooms = Vec::new(); let avatar_url = &current_avatar_url;
for room_id in all_joined_rooms { let blurhash = &current_blurhash;
let Ok(content) = services let displayname = &displayname;
.rooms
.state_accessor
.room_state_get_content(room_id, &StateEventType::RoomMember, user_id.as_str())
.await
else {
continue;
};
let pdu = PduBuilder::state(
user_id.to_string(),
&RoomMemberEventContent {
displayname: displayname.clone(),
join_authorized_via_users_server: None,
..content
},
);
joined_rooms.push((pdu, room_id));
}
update_all_rooms(services, joined_rooms, user_id).await;
Ok(())
}
pub async fn update_avatar_url(
services: &Services, user_id: &UserId, avatar_url: Option<OwnedMxcUri>, blurhash: Option<String>,
all_joined_rooms: &[OwnedRoomId],
) -> Result<()> {
let current_avatar_url = services.users.avatar_url(user_id).await.ok();
let current_blurhash = services.users.blurhash(user_id).await.ok();
if current_avatar_url == avatar_url && current_blurhash == blurhash {
return Ok(());
}
services.users.set_avatar_url(user_id, avatar_url.clone());
services.users.set_blurhash(user_id, blurhash.clone());
// Send a new join membership event into all joined rooms
let avatar_url = &avatar_url;
let blurhash = &blurhash;
let all_joined_rooms: Vec<_> = all_joined_rooms let all_joined_rooms: Vec<_> = all_joined_rooms
.iter() .iter()
.try_stream() .try_stream()
.and_then(|room_id: &OwnedRoomId| async move { .and_then(|room_id: &OwnedRoomId| async move {
let content = services
.rooms
.state_accessor
.room_state_get_content(room_id, &StateEventType::RoomMember, user_id.as_str())
.await?;
let pdu = PduBuilder::state( let pdu = PduBuilder::state(
user_id.to_string(), user_id.to_string(),
&RoomMemberEventContent { &RoomMemberEventContent {
displayname: displayname.clone(),
membership: MembershipState::Join,
avatar_url: avatar_url.clone(), avatar_url: avatar_url.clone(),
blurhash: blurhash.clone(), blurhash: blurhash.clone(),
join_authorized_via_users_server: None, join_authorized_via_users_server: None,
..content reason: None,
is_direct: None,
third_party_invite: None,
}, },
); );
@ -377,8 +343,59 @@ pub async fn update_avatar_url(
.await; .await;
update_all_rooms(services, all_joined_rooms, user_id).await; update_all_rooms(services, all_joined_rooms, user_id).await;
}
Ok(()) pub async fn update_avatar_url(
services: &Services, user_id: &UserId, avatar_url: Option<OwnedMxcUri>, blurhash: Option<String>,
all_joined_rooms: &[OwnedRoomId],
) {
let (current_avatar_url, current_blurhash, current_displayname) = join3(
services.users.avatar_url(user_id),
services.users.blurhash(user_id),
services.users.displayname(user_id),
)
.await;
let current_avatar_url = current_avatar_url.ok();
let current_blurhash = current_blurhash.ok();
let current_displayname = current_displayname.ok();
if current_avatar_url == avatar_url && current_blurhash == blurhash {
return;
}
services.users.set_avatar_url(user_id, avatar_url.clone());
services.users.set_blurhash(user_id, blurhash.clone());
// Send a new join membership event into all joined rooms
let avatar_url = &avatar_url;
let blurhash = &blurhash;
let displayname = &current_displayname;
let all_joined_rooms: Vec<_> = all_joined_rooms
.iter()
.try_stream()
.and_then(|room_id: &OwnedRoomId| async move {
let pdu = PduBuilder::state(
user_id.to_string(),
&RoomMemberEventContent {
avatar_url: avatar_url.clone(),
blurhash: blurhash.clone(),
membership: MembershipState::Join,
displayname: displayname.clone(),
join_authorized_via_users_server: None,
reason: None,
is_direct: None,
third_party_invite: None,
},
);
Ok((pdu, room_id))
})
.ignore_err()
.collect()
.await;
update_all_rooms(services, all_joined_rooms, user_id).await;
} }
pub async fn update_all_rooms( pub async fn update_all_rooms(
@ -392,7 +409,7 @@ pub async fn update_all_rooms(
.build_and_append_pdu(pdu_builder, user_id, room_id, &state_lock) .build_and_append_pdu(pdu_builder, user_id, room_id, &state_lock)
.await .await
{ {
warn!(%user_id, %room_id, %e, "Failed to update/send new profile join membership update in room"); warn!(%user_id, %room_id, "Failed to update/send new profile join membership update in room: {e}");
} }
} }
} }