feat: allow deprioritizing servers for join requests

Implements #1549.
This commit is contained in:
éźera
2026-04-07 11:47:33 -05:00
committed by Ellis Git
parent bedec72489
commit 2ca7149a7f
4 changed files with 89 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
Implemented option to deprioritize servers for room join requests. Contributed by @ezera.
+14
View File
@@ -1409,6 +1409,20 @@
#
#ignore_messages_from_server_names = []
# List of server names that continuwuity will deprioritize (try last) when
# a client requests to join a room.
#
# This can be used to potentially speed up room join requests, by
# deprioritizing sending join requests through servers that are known to
# be large or slow.
#
# continuwuity will still send join requests to servers in this list if
# the room couldn't be joined via other servers it federates with.
#
# example: ["example.com"]
#
#deprioritize_joins_through_servers = []
# Send messages from users that the user has ignored to the client.
#
# There is no way for clients to receive messages sent while a user was
+58
View File
@@ -113,6 +113,7 @@ pub(crate) async fn join_room_by_id_route(
servers.sort_unstable();
servers.dedup();
shuffle(&mut servers);
let servers = deprioritize(servers, &services.config.deprioritize_joins_through_servers);
join_room_by_id_helper(
&services,
@@ -241,6 +242,7 @@ pub(crate) async fn join_room_by_id_or_alias_route(
},
};
let servers = deprioritize(servers, &services.config.deprioritize_joins_through_servers);
let join_room_response = join_room_by_id_helper(
&services,
sender_user,
@@ -890,3 +892,59 @@ async fn make_join_request(
info!("All {} servers were unable to assist in joining {room_id} :(", servers.len());
Err!(BadServerResponse("No server available to assist in joining."))
}
/// Moves deprioritized servers (if any) to the back of the list.
///
/// No-op if we aren't given any servers to deprioritize.
fn deprioritize(
servers: Vec<OwnedServerName>,
deprioritized: &[OwnedServerName],
) -> Vec<OwnedServerName> {
if deprioritized.is_empty() {
return servers;
}
let (mut depr, mut servers): (Vec<_>, Vec<_>) =
servers.into_iter().partition(|s| deprioritized.contains(s));
servers.append(&mut depr);
servers
}
#[cfg(test)]
mod tests {
use ruma::OwnedServerName;
use super::*;
#[test]
fn deprioritizing_servers_works() -> Result<(), Box<dyn std::error::Error>> {
let servers = vec![
"example.com".try_into()?,
"slow.invalid".try_into()?,
"example.org".try_into()?,
];
let depr = vec!["slow.invalid".try_into()?];
let expected: Vec<OwnedServerName> = vec![
"example.com".try_into()?,
"example.org".try_into()?,
"slow.invalid".try_into()?,
];
let servers = deprioritize(servers, &depr);
assert_eq!(servers, expected);
Ok(())
}
#[test]
fn empty_deprioritized_is_noop() -> Result<(), Box<dyn std::error::Error>> {
let servers = vec![
"example.com".try_into()?,
"slow.invalid".try_into()?,
"example.org".try_into()?,
];
let depr_servers = deprioritize(servers.clone(), &[]);
assert_eq!(depr_servers, servers);
Ok(())
}
}
+16
View File
@@ -1630,6 +1630,22 @@ pub struct Config {
#[serde(default, with = "serde_regex")]
pub ignore_messages_from_server_names: RegexSet,
/// List of server names that continuwuity will deprioritize (try last) when
/// a client requests to join a room.
///
/// This can be used to potentially speed up room join requests, by
/// deprioritizing sending join requests through servers that are known to
/// be large or slow.
///
/// continuwuity will still send join requests to servers in this list if
/// the room couldn't be joined via other servers it federates with.
///
/// example: ["example.com"]
///
/// default: []
#[serde(default = "Vec::new")]
pub deprioritize_joins_through_servers: Vec<OwnedServerName>,
/// Send messages from users that the user has ignored to the client.
///
/// There is no way for clients to receive messages sent while a user was