Add configuration for make_join and send_join attempt counts.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-12-02 06:44:01 +00:00
parent fb0c2a2832
commit f311332bad
4 changed files with 75 additions and 8 deletions

View File

@@ -5,7 +5,7 @@ use ruma::{
RoomId, RoomOrAliasId,
api::client::membership::{join_room_by_id, join_room_by_id_or_alias},
};
use tuwunel_core::Result;
use tuwunel_core::{Result, warn};
use super::banned_room_check;
use crate::{Ruma, client::membership::get_join_params};
@@ -36,7 +36,8 @@ pub(crate) async fn join_room_by_id_route(
let state_lock = services.state.mutex.lock(&room_id).await;
services
let mut errors = 0_usize;
while let Err(e) = services
.membership
.join(
sender_user,
@@ -47,7 +48,17 @@ pub(crate) async fn join_room_by_id_route(
&state_lock,
)
.boxed()
.await?;
.await
{
errors = errors.saturating_add(1);
if errors >= services.config.max_join_attempts_per_join_request {
warn!(
"Several servers failed. Giving up for this request. Try again for different \
server selection."
);
return Err(e);
}
}
drop(state_lock);
@@ -80,7 +91,8 @@ pub(crate) async fn join_room_by_id_or_alias_route(
let state_lock = services.state.mutex.lock(&room_id).await;
services
let mut errors = 0_usize;
while let Err(e) = services
.membership
.join(
sender_user,
@@ -91,7 +103,17 @@ pub(crate) async fn join_room_by_id_or_alias_route(
&state_lock,
)
.boxed()
.await?;
.await
{
errors = errors.saturating_add(1);
if errors >= services.config.max_join_attempts_per_join_request {
warn!(
"Several servers failed. Giving up for this request. Try again for different \
server selection."
);
return Err(e);
}
}
drop(state_lock);

View File

@@ -1757,6 +1757,26 @@ pub struct Config {
)]
pub deprioritize_joins_through_servers: RegexSet,
/// Maximum make_join requests to attempt within each join attempt. Each
/// attempt tries a different server, as each server is only tried once;
/// though retries can occur when the join request as a whole is retried.
///
/// default: 48
#[serde(default = "default_max_make_join_attempts_per_join_attempt")]
pub max_make_join_attempts_per_join_attempt: usize,
/// Maximum join attempts to conduct per client join request. Each join
/// attempt consists of one or more make_join requests limited above, and a
/// single send_join request. This value allows for additional servers to
/// act as the join-server prior to reporting the last error back to the
/// client, which can be frustrating for users. Therefor the default value
/// is greater than one, but less than excessively exceeding the client's
/// request timeout, though that may not be avoidable in some cases.
///
/// default: 3
#[serde(default = "default_max_join_attempts_per_join_request")]
pub max_join_attempts_per_join_request: usize,
/// Retry failed and incomplete messages to remote servers immediately upon
/// startup. This is called bursting. If this is disabled, said messages may
/// not be delivered until more messages are queued for that server. Do not
@@ -2997,3 +3017,7 @@ fn default_deprioritize_joins_through_servers() -> RegexSet {
}
fn default_one_time_key_limit() -> usize { 256 }
fn default_max_make_join_attempts_per_join_attempt() -> usize { 48 }
fn default_max_join_attempts_per_join_request() -> usize { 3 }

View File

@@ -806,10 +806,15 @@ async fn make_join_request(
return make_join_response_and_server;
}
if make_join_counter > 40 {
let max_attempts = self
.services
.config
.max_make_join_attempts_per_join_attempt;
if make_join_counter >= max_attempts {
warn!(?remote_server, "last make_join failure reason: {e}");
warn!(
"40 servers failed to provide valid make_join response, assuming no server \
can assist in joining."
"{max_attempts} servers failed to provide valid make_join response, \
assuming no server can assist in joining."
);
make_join_response_and_server =
Err!(BadServerResponse("No server available to assist in joining."));

View File

@@ -1516,6 +1516,22 @@
#
#deprioritize_joins_through_servers = ["matrix\.org"]
# Maximum make_join requests to attempt within each join attempt. Each
# attempt tries a different server, as each server is only tried once;
# though retries can occur when the join request as a whole is retried.
#
#max_make_join_attempts_per_join_attempt = 48
# Maximum join attempts to conduct per client join request. Each join
# attempt consists of one or more make_join requests limited above, and a
# single send_join request. This value allows for additional servers to
# act as the join-server prior to reporting the last error back to the
# client, which can be frustrating for users. Therefor the default value
# is greater than one, but less than excessively exceeding the client's
# request timeout, though that may not be avoidable in some cases.
#
#max_join_attempts_per_join_request = 3
# Retry failed and incomplete messages to remote servers immediately upon
# startup. This is called bursting. If this is disabled, said messages may
# not be delivered until more messages are queued for that server. Do not