Add config circuit-breaker for heroes calculations during sync.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-11-19 03:07:15 +00:00
parent e60e86e9ed
commit 120ab1d068
4 changed files with 45 additions and 12 deletions

View File

@@ -1262,7 +1262,10 @@ async fn calculate_counts(
let small_room = joined_member_count.saturating_add(invited_member_count) <= 5; let small_room = joined_member_count.saturating_add(invited_member_count) <= 5;
let heroes: OptionFuture<_> = small_room let heroes: OptionFuture<_> = services
.config
.calculate_heroes
.and_is(small_room)
.then(|| calculate_heroes(services, room_id, sender_user)) .then(|| calculate_heroes(services, room_id, sender_user))
.into(); .into();

View File

@@ -327,20 +327,27 @@ async fn handle_room(
.boxed() .boxed()
.await; .await;
let (heroes, hero_name, heroes_avatar) = calculate_heroes( let heroes: OptionFuture<_> = services
services, .config
sender_user, .calculate_heroes
room_id, .then(|| {
room_name.as_ref(), calculate_heroes(
room_avatar.as_deref(), services,
) sender_user,
.await?; room_id,
room_name.as_ref(),
room_avatar.as_deref(),
)
})
.into();
let (heroes, heroes_name, heroes_avatar) = heroes.await.unwrap_or_default();
Ok(response::Room { Ok(response::Room {
initial: roomsince.eq(&0).then_some(true), initial: roomsince.eq(&0).then_some(true),
lists: lists.clone(), lists: lists.clone(),
membership: membership.clone(), membership: membership.clone(),
name: room_name.or(hero_name), name: room_name.or(heroes_name),
avatar: JsOption::from_option(room_avatar.or(heroes_avatar)), avatar: JsOption::from_option(room_avatar.or(heroes_avatar)),
is_dm, is_dm,
heroes, heroes,
@@ -365,8 +372,9 @@ async fn calculate_heroes(
room_id: &RoomId, room_id: &RoomId,
room_name: Option<&DisplayName>, room_name: Option<&DisplayName>,
room_avatar: Option<&MxcUri>, room_avatar: Option<&MxcUri>,
) -> Result<(Option<Heroes>, Option<DisplayName>, Option<OwnedMxcUri>)> { ) -> (Option<Heroes>, Option<DisplayName>, Option<OwnedMxcUri>) {
const MAX_HEROES: usize = 5; const MAX_HEROES: usize = 5;
let heroes: Heroes = services let heroes: Heroes = services
.state_cache .state_cache
.room_members(room_id) .room_members(room_id)
@@ -443,5 +451,5 @@ async fn calculate_heroes(
}) })
.flatten(); .flatten();
Ok((Some(heroes), hero_name, heroes_avatar)) (Some(heroes), hero_name, heroes_avatar)
} }

View File

@@ -1336,6 +1336,17 @@ pub struct Config {
#[serde(default)] #[serde(default)]
pub push_everything: bool, pub push_everything: bool,
/// Setting to false disables the heroes calculation made by sliding and
/// legacy client sync. The heroes calculation is mandated by the Matrix
/// specification and your client may not operate properly unless this
/// option is set to true.
///
/// This option is intended for custom software deployments seeking purely
/// to minimize unused resources; the overall savings are otherwise
/// negligible.
#[serde(default = "true_fn")]
pub calculate_heroes: bool,
/// Allow local (your server only) presence updates/requests. /// Allow local (your server only) presence updates/requests.
/// ///
/// Note that presence on tuwunel is very fast unlike Synapse's. If using /// Note that presence on tuwunel is very fast unlike Synapse's. If using

View File

@@ -1136,6 +1136,17 @@
# #
#push_everything = false #push_everything = false
# Setting to false disables the heroes calculation made by sliding and
# legacy client sync. The heroes calculation is mandated by the Matrix
# specification and your client may not operate properly unless this
# option is set to true.
#
# This option is intended for custom software deployments seeking purely
# to minimize unused resources; the overall savings are otherwise
# negligible.
#
#calculate_heroes = true
# Allow local (your server only) presence updates/requests. # Allow local (your server only) presence updates/requests.
# #
# Note that presence on tuwunel is very fast unlike Synapse's. If using # Note that presence on tuwunel is very fast unlike Synapse's. If using