try finding more servers for federation hierarchy instead of room ID server name

just the room ID server name is terrible

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-04-22 00:44:35 -04:00 committed by June
parent 69968b94ea
commit b3f03d307d

View file

@ -30,9 +30,9 @@ use ruma::{
OwnedRoomId, OwnedServerName, RoomId, ServerName, UInt, UserId, OwnedRoomId, OwnedServerName, RoomId, ServerName, UInt, UserId,
}; };
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tracing::{debug, error, warn}; use tracing::{debug, error, info, warn};
use crate::{services, Error, Result}; use crate::{debug_info, services, Error, Result};
pub struct CachedSpaceHierarchySummary { pub struct CachedSpaceHierarchySummary {
summary: SpaceHierarchyParentSummary, summary: SpaceHierarchyParentSummary,
@ -425,8 +425,36 @@ impl Service {
} }
async fn get_summary_and_children_federation( async fn get_summary_and_children_federation(
&self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &Vec<OwnedServerName>, &self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &[OwnedServerName],
) -> Result<Option<SummaryAccessibility>> { ) -> Result<Option<SummaryAccessibility>> {
// try to find more servers to fetch hierachy from if the only
// choice is the room ID's server name (usually dead)
//
// all spaces are normal rooms, so they should always have at least
// 1 admin in it which has a far higher chance of their server still
// being alive
let power_levels: ruma::events::room::power_levels::RoomPowerLevelsEventContent = services()
.rooms
.state_accessor
.room_state_get(current_room, &StateEventType::RoomPowerLevels, "")?
.map(|ev| {
serde_json::from_str(ev.content.get())
.map_err(|_| Error::bad_database("invalid m.room.power_levels event"))
})
.transpose()?
.unwrap_or_default();
// add server names of the list of admins in the room for backfill server
via.to_owned().extend(
power_levels
.users
.iter()
.filter(|(_, level)| **level > power_levels.users_default)
.map(|(user_id, _)| user_id.server_name())
.filter(|server| server != &services().globals.server_name())
.map(ToOwned::to_owned),
);
for server in via { for server in via {
debug!("Asking {server} for /hierarchy"); debug!("Asking {server} for /hierarchy");
if let Ok(response) = services() if let Ok(response) = services()
@ -440,7 +468,7 @@ impl Service {
) )
.await .await
{ {
debug!("Got response from {server} for /hierarchy\n{response:?}"); debug_info!("Got response from {server} for /hierarchy\n{response:?}");
let summary = response.room.clone(); let summary = response.room.clone();
self.roomid_spacehierarchy_cache.lock().await.insert( self.roomid_spacehierarchy_cache.lock().await.insert(
@ -511,7 +539,7 @@ impl Service {
} }
async fn get_summary_and_children_client( async fn get_summary_and_children_client(
&self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &Vec<OwnedServerName>, &self, current_room: &OwnedRoomId, suggested_only: bool, user_id: &UserId, via: &[OwnedServerName],
) -> Result<Option<SummaryAccessibility>> { ) -> Result<Option<SummaryAccessibility>> {
if let Ok(Some(response)) = self if let Ok(Some(response)) = self
.get_summary_and_children_local(current_room, Identifier::UserId(user_id)) .get_summary_and_children_local(current_room, Identifier::UserId(user_id))
@ -625,13 +653,16 @@ impl Service {
&self, sender_user: &UserId, room_id: &RoomId, limit: usize, skip: usize, max_depth: usize, &self, sender_user: &UserId, room_id: &RoomId, limit: usize, skip: usize, max_depth: usize,
suggested_only: bool, suggested_only: bool,
) -> Result<client::space::get_hierarchy::v1::Response> { ) -> Result<client::space::get_hierarchy::v1::Response> {
let via = match room_id.server_name() {
Some(server_name) => vec![server_name.to_owned()],
None => vec![],
};
match self match self
.get_summary_and_children_client(&room_id.to_owned(), suggested_only, sender_user, &via) .get_summary_and_children_client(
&room_id.to_owned(),
suggested_only,
sender_user,
&match room_id.server_name() {
Some(server_name) => vec![server_name.to_owned()],
None => vec![],
},
)
.await? .await?
{ {
Some(SummaryAccessibility::Accessible(summary)) => { Some(SummaryAccessibility::Accessible(summary)) => {