From 120ab1d0688d82028d0ccbb041d74143a58d0a21 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 19 Nov 2025 03:07:15 +0000 Subject: [PATCH] Add config circuit-breaker for heroes calculations during sync. Signed-off-by: Jason Volk --- src/api/client/sync/v3.rs | 5 ++++- src/api/client/sync/v5/rooms.rs | 30 +++++++++++++++++++----------- src/core/config/mod.rs | 11 +++++++++++ tuwunel-example.toml | 11 +++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index 40430cf6..c40a73b9 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -1262,7 +1262,10 @@ async fn calculate_counts( 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)) .into(); diff --git a/src/api/client/sync/v5/rooms.rs b/src/api/client/sync/v5/rooms.rs index 1e1cf598..f9d9e41c 100644 --- a/src/api/client/sync/v5/rooms.rs +++ b/src/api/client/sync/v5/rooms.rs @@ -327,20 +327,27 @@ async fn handle_room( .boxed() .await; - let (heroes, hero_name, heroes_avatar) = calculate_heroes( - services, - sender_user, - room_id, - room_name.as_ref(), - room_avatar.as_deref(), - ) - .await?; + let heroes: OptionFuture<_> = services + .config + .calculate_heroes + .then(|| { + calculate_heroes( + services, + sender_user, + 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 { initial: roomsince.eq(&0).then_some(true), lists: lists.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)), is_dm, heroes, @@ -365,8 +372,9 @@ async fn calculate_heroes( room_id: &RoomId, room_name: Option<&DisplayName>, room_avatar: Option<&MxcUri>, -) -> Result<(Option, Option, Option)> { +) -> (Option, Option, Option) { const MAX_HEROES: usize = 5; + let heroes: Heroes = services .state_cache .room_members(room_id) @@ -443,5 +451,5 @@ async fn calculate_heroes( }) .flatten(); - Ok((Some(heroes), hero_name, heroes_avatar)) + (Some(heroes), hero_name, heroes_avatar) } diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 998b3fb1..6e7b44b3 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1336,6 +1336,17 @@ pub struct Config { #[serde(default)] 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. /// /// Note that presence on tuwunel is very fast unlike Synapse's. If using diff --git a/tuwunel-example.toml b/tuwunel-example.toml index d7926cbb..7f10476a 100644 --- a/tuwunel-example.toml +++ b/tuwunel-example.toml @@ -1136,6 +1136,17 @@ # #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. # # Note that presence on tuwunel is very fast unlike Synapse's. If using