refactor: rename automatic_relay_management to autorelay

"automatic_relay_management" is a long unwiedly name with no UI using the mode yet,
so let's rename it to something more succinct: autorelay
This commit is contained in:
holger krekel
2026-08-23 18:08:14 +02:00
parent 96f051a2f0
commit a344cab046
8 changed files with 50 additions and 66 deletions

View File

@@ -1,3 +1,18 @@
//! # Automatic relay handling (experimental, still in development)
//!
//! Chatmail relays create an account on first login,
//! so a profile can add further transports on its own without user interaction.
//! Candidate hosts come from the `relay_candidates` table,
//! which migrations seed with a list of known chatmail relays.
//!
//! Status of implementation:
//! Additions are attempted right before going into IMAP IDLE,
//! i.e. only while connected and with nothing more important to do,
//! and only if a UI opted in via [`Config::Autorelay`].
//! Once a profile has reached `NUM_TRANSPORTS_TARGET` transports,
//! [`Config::AutorelayFinished`] is set and nothing is ever added again,
//! so deleting a transport later does not pull in a replacement.
use std::pin::Pin;
use anyhow::Result;
@@ -46,9 +61,7 @@ async fn maybe_add_additional_relays_inner(context: &Context, skip_network: bool
// Housekeeping or automatic relay management is already running in another thread, do nothing.
return Ok(false);
};
let last_timestamp = context
.get_config_i64(Config::LastAutomaticRelayManagement)
.await?;
let last_timestamp = context.get_config_i64(Config::LastAutorelay).await?;
if last_timestamp > now {
warn!(
context,
@@ -57,22 +70,16 @@ async fn maybe_add_additional_relays_inner(context: &Context, skip_network: bool
} else if last_timestamp > now.saturating_sub(AUTOMATIC_ADDITION_DEBOUNCE_SECONDS) {
return Ok(false);
}
if !context
.get_config_bool(Config::AutomaticRelayManagement)
.await?
{
if !context.get_config_bool(Config::Autorelay).await? {
return Ok(false);
}
if context
.get_config_bool(Config::AutomaticRelayManagementFinished)
.await?
{
if context.get_config_bool(Config::AutorelayFinished).await? {
return Ok(false);
}
// Set the config at the beginning to avoid endless loops.
// Race conditions are not a concern because we locked the mutex.
context
.set_config_internal(Config::LastAutomaticRelayManagement, Some(&now.to_string()))
.set_config_internal(Config::LastAutorelay, Some(&now.to_string()))
.await?;
let mut relay_added = false;
@@ -80,10 +87,7 @@ async fn maybe_add_additional_relays_inner(context: &Context, skip_network: bool
for _ in 0..NUM_TRANSPORTS_TARGET {
if context.count_transports().await? >= NUM_TRANSPORTS_TARGET {
context
.set_config_internal(
Config::AutomaticRelayManagementFinished,
config::from_bool(true),
)
.set_config_internal(Config::AutorelayFinished, config::from_bool(true))
.await?;
return Ok(relay_added);
@@ -175,4 +179,4 @@ pub(crate) fn login_param_from_host(host: &str) -> EnteredLoginParam {
}
#[cfg(test)]
mod automatic_relay_management_tests;
mod autorelay_tests;

View File

@@ -73,12 +73,9 @@ async fn test_load_relay_candidates_multiple() -> Result<()> {
Ok(())
}
async fn assert_automatic_relay_management_does_nothing(t: &TestContext) {
async fn assert_autorelay_does_nothing(t: &TestContext) {
let transports_before = t.count_transports().await.unwrap();
let config_before = t
.get_config_i64(Config::LastAutomaticRelayManagement)
.await
.unwrap();
let config_before = t.get_config_i64(Config::LastAutorelay).await.unwrap();
let skip_network = false; // No need to skip network, nothing is supposed to happen
let relay_added = maybe_add_additional_relays_inner(t, skip_network)
@@ -86,10 +83,7 @@ async fn assert_automatic_relay_management_does_nothing(t: &TestContext) {
.unwrap();
assert_eq!(relay_added, false);
let config_after = t
.get_config_i64(Config::LastAutomaticRelayManagement)
.await
.unwrap();
let config_after = t.get_config_i64(Config::LastAutorelay).await.unwrap();
let transports_after = t.count_transports().await.unwrap();
assert_eq!(config_after, config_before);
@@ -105,7 +99,7 @@ async fn test_maybe_add_additional_relays_mutex_held() -> Result<()> {
// already running housekeeping or relay management.
let _lock = t.background_task_mutex.lock().await;
assert_automatic_relay_management_does_nothing(t).await;
assert_autorelay_does_nothing(t).await;
Ok(())
}
@@ -117,13 +111,10 @@ async fn test_maybe_add_additional_relays_debounce() -> Result<()> {
let some_seconds_ago = time() - 10;
// Pretend automatic relay management just ran.
t.set_config_internal(
Config::LastAutomaticRelayManagement,
Some(&some_seconds_ago.to_string()),
)
.await?;
t.set_config_internal(Config::LastAutorelay, Some(&some_seconds_ago.to_string()))
.await?;
assert_automatic_relay_management_does_nothing(t).await;
assert_autorelay_does_nothing(t).await;
Ok(())
}
@@ -132,7 +123,7 @@ async fn test_maybe_add_additional_relays_debounce() -> Result<()> {
async fn test_maybe_add_additional_relays_disabled() {
// By default, automatic relay management is disabled:
let t = &TestContext::new_alice().await;
assert_automatic_relay_management_does_nothing(t).await;
assert_autorelay_does_nothing(t).await;
}
/// Runs maybe_add_additional_relays_inner(), then deletes one of the transports.
@@ -158,11 +149,8 @@ async fn test_maybe_add_additional_relays_does_nothing_after_finishing_once() ->
let transports_count = t.count_transports().await?;
assert_eq!(transports_count, NUM_TRANSPORTS_TARGET - 1);
assert!(
t.get_config_bool(Config::AutomaticRelayManagementFinished)
.await?
);
assert_automatic_relay_management_does_nothing(t).await;
assert!(t.get_config_bool(Config::AutorelayFinished).await?);
assert_autorelay_does_nothing(t).await;
Ok(())
}
@@ -187,9 +175,7 @@ async fn test_maybe_add_additional_relays_add_one() -> Result<()> {
let relay_added = maybe_add_additional_relays_inner(t, skip_network).await?;
assert!(relay_added);
let config_after = t
.get_config_i64(Config::LastAutomaticRelayManagement)
.await?;
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
assert!(config_after >= now);
let transports_after = t.count_transports().await?;
@@ -218,9 +204,7 @@ async fn test_maybe_add_additional_relays_add_multiple() -> Result<()> {
let relay_added = maybe_add_additional_relays_inner(t, skip_network).await?;
assert!(relay_added);
let config_after = t
.get_config_i64(Config::LastAutomaticRelayManagement)
.await?;
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
assert!(config_after >= now);
let transports_after = t.count_transports().await?;
@@ -253,9 +237,7 @@ async fn test_maybe_add_additional_relays_failure() -> Result<()> {
assert_eq!(relay_added, false);
// The config is still updated:
let config_after = t
.get_config_i64(Config::LastAutomaticRelayManagement)
.await?;
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
assert!(config_after >= now);
let transports_after = t.count_transports().await?;
@@ -286,7 +268,7 @@ async fn test_maybe_add_additional_relays_failure() -> Result<()> {
async fn enable_config(context: &Context) {
context
.set_config_bool(Config::AutomaticRelayManagement, true)
.set_config_bool(Config::Autorelay, true)
.await
.unwrap();
}

View File

@@ -353,13 +353,13 @@ pub enum Config {
LastCantDecryptOutgoingMsgs,
/// Timestamp of the last time automatic relay management was run
LastAutomaticRelayManagement,
LastAutorelay,
/// Whether to automatically add/remove transports
AutomaticRelayManagement,
Autorelay,
/// Whether automatic relay management successfully added the desired number of relays
AutomaticRelayManagementFinished,
AutorelayFinished,
/// Whether to avoid using IMAP IDLE even if the server supports it.
///

View File

@@ -749,7 +749,7 @@ mod tests {
use crate::tools::SystemTime;
use super::*;
use crate::automatic_relay_management::login_param_from_host;
use crate::autorelay::login_param_from_host;
use crate::config::Config;
use crate::login_param::EnteredImapLoginParam;
use crate::sql::update_transport_last_rcvd_timestamp;

View File

@@ -1047,20 +1047,18 @@ impl Context {
.to_string(),
);
res.insert(
"last_automatic_relay_management",
self.get_config_i64(Config::LastAutomaticRelayManagement)
"last_autorelay",
self.get_config_i64(Config::LastAutorelay)
.await?
.to_string(),
);
res.insert(
"automatic_relay_management",
self.get_config_bool(Config::AutomaticRelayManagement)
.await?
.to_string(),
"autorelay",
self.get_config_bool(Config::Autorelay).await?.to_string(),
);
res.insert(
"automatic_relay_management_finished",
self.get_config_bool(Config::AutomaticRelayManagementFinished)
"autorelay_finished",
self.get_config_bool(Config::AutorelayFinished)
.await?
.to_string(),
);

View File

@@ -53,9 +53,9 @@ impl Session {
// we try to add additional relays right before going into IDLE mode,
// because we are connected and don't have anything important to do.
tokio::task::spawn(
crate::automatic_relay_management::maybe_add_additional_relays(context.clone()),
);
tokio::task::spawn(crate::autorelay::maybe_add_additional_relays(
context.clone(),
));
let mut handle = self.inner.idle();
handle

View File

@@ -55,7 +55,7 @@ pub use events::*;
mod aheader;
pub mod appversions;
mod automatic_relay_management;
mod autorelay;
pub mod blob;
pub mod calls;
pub mod chat;

View File

@@ -11,7 +11,7 @@ use deltachat_contact_tools::{ContactAddress, addr_normalize, may_be_valid_addr}
use percent_encoding::{NON_ALPHANUMERIC, percent_decode_str, percent_encode};
use serde::Deserialize;
use crate::automatic_relay_management::login_param_from_host;
use crate::autorelay::login_param_from_host;
use crate::config::Config;
use crate::contact::{Contact, ContactId, Origin};
use crate::context::Context;