Improve backfill server selection post-v12 power and creator changes.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-11-27 00:14:12 +00:00
parent 0bbc228f7a
commit d2d6a98180

View File

@@ -1,15 +1,12 @@
use std::iter::once; use std::{collections::HashSet, iter::once};
use futures::{ use futures::{
FutureExt, StreamExt, TryFutureExt, FutureExt, StreamExt, TryFutureExt,
future::{join, try_join, try_join4}, future::{join, try_join, try_join4},
}; };
use rand::seq::SliceRandom;
use ruma::{ use ruma::{
CanonicalJsonObject, EventId, RoomId, ServerName, CanonicalJsonObject, EventId, RoomId, ServerName, api::federation, events::TimelineEventType,
api::federation,
events::{
StateEventType, TimelineEventType, room::power_levels::RoomPowerLevelsEventContent,
},
uint, uint,
}; };
use serde_json::value::RawValue as RawJsonValue; use serde_json::value::RawValue as RawJsonValue;
@@ -20,8 +17,8 @@ use tuwunel_core::{
pdu::{PduCount, PduId, RawPduId}, pdu::{PduCount, PduId, RawPduId},
}, },
utils::{ utils::{
IterStream, ReadyExt, BoolExt, IterStream, ReadyExt,
future::{BoolExt, TryExtExt}, future::{BoolExt as FutureBoolExt, TryExtExt},
}, },
validated, warn, validated, warn,
}; };
@@ -72,19 +69,43 @@ pub async fn backfill_if_required(&self, room_id: &RoomId, from: PduCount) -> Re
let power_levels = self let power_levels = self
.services .services
.state_accessor .state_accessor
.room_state_get_content(room_id, &StateEventType::RoomPowerLevels, "") .get_power_levels(room_id);
.map_ok(|content: RoomPowerLevelsEventContent| content)
.unwrap_or_default();
let (canonical_alias, power_levels) = join(canonical_alias, power_levels).await; let (canonical_alias, power_levels) = join(canonical_alias, power_levels).await;
let room_mods = power_levels let power_servers = power_levels
.users
.iter() .iter()
.filter_map(|(user_id, level)| { .flat_map(|power| {
(*level > power_levels.users_default && !self.services.globals.user_is_local(user_id)) power
.rules
.privileged_creators
.iter()
.flat_map(|creators| creators.iter())
})
.chain(power_levels.iter().flat_map(|power| {
power
.users
.iter()
.filter_map(|(user_id, level)| level.gt(&power.users_default).then_some(user_id))
}))
.filter_map(|user_id| {
self.services
.globals
.user_is_local(user_id)
.is_false()
.then_some(user_id.server_name()) .then_some(user_id.server_name())
}); })
.collect::<HashSet<_>>();
let power_servers = {
let mut vec: Vec<_> = power_servers
.into_iter()
.map(ToOwned::to_owned)
.collect();
vec.shuffle(&mut rand::thread_rng());
vec.into_iter().stream()
};
let canonical_room_alias_server = once(canonical_alias) let canonical_room_alias_server = once(canonical_alias)
.filter_map(Result::ok) .filter_map(Result::ok)
@@ -100,9 +121,7 @@ pub async fn backfill_if_required(&self, room_id: &RoomId, from: PduCount) -> Re
.map(ToOwned::to_owned) .map(ToOwned::to_owned)
.stream(); .stream();
let mut servers = room_mods let mut servers = power_servers
.stream()
.map(ToOwned::to_owned)
.chain(canonical_room_alias_server) .chain(canonical_room_alias_server)
.chain(trusted_servers) .chain(trusted_servers)
.ready_filter(|server_name| !self.services.globals.server_is_ours(server_name)) .ready_filter(|server_name| !self.services.globals.server_is_ours(server_name))