mirror of
https://github.com/chatmail/core.git
synced 2026-10-02 03:00:40 +03:00
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:
@@ -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 std::pin::Pin;
|
||||||
|
|
||||||
use anyhow::Result;
|
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.
|
// Housekeeping or automatic relay management is already running in another thread, do nothing.
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
let last_timestamp = context
|
let last_timestamp = context.get_config_i64(Config::LastAutorelay).await?;
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await?;
|
|
||||||
if last_timestamp > now {
|
if last_timestamp > now {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
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) {
|
} else if last_timestamp > now.saturating_sub(AUTOMATIC_ADDITION_DEBOUNCE_SECONDS) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
if !context
|
if !context.get_config_bool(Config::Autorelay).await? {
|
||||||
.get_config_bool(Config::AutomaticRelayManagement)
|
|
||||||
.await?
|
|
||||||
{
|
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
if context
|
if context.get_config_bool(Config::AutorelayFinished).await? {
|
||||||
.get_config_bool(Config::AutomaticRelayManagementFinished)
|
|
||||||
.await?
|
|
||||||
{
|
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
// Set the config at the beginning to avoid endless loops.
|
// Set the config at the beginning to avoid endless loops.
|
||||||
// Race conditions are not a concern because we locked the mutex.
|
// Race conditions are not a concern because we locked the mutex.
|
||||||
context
|
context
|
||||||
.set_config_internal(Config::LastAutomaticRelayManagement, Some(&now.to_string()))
|
.set_config_internal(Config::LastAutorelay, Some(&now.to_string()))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut relay_added = false;
|
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 {
|
for _ in 0..NUM_TRANSPORTS_TARGET {
|
||||||
if context.count_transports().await? >= NUM_TRANSPORTS_TARGET {
|
if context.count_transports().await? >= NUM_TRANSPORTS_TARGET {
|
||||||
context
|
context
|
||||||
.set_config_internal(
|
.set_config_internal(Config::AutorelayFinished, config::from_bool(true))
|
||||||
Config::AutomaticRelayManagementFinished,
|
|
||||||
config::from_bool(true),
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
return Ok(relay_added);
|
return Ok(relay_added);
|
||||||
@@ -175,4 +179,4 @@ pub(crate) fn login_param_from_host(host: &str) -> EnteredLoginParam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod automatic_relay_management_tests;
|
mod autorelay_tests;
|
||||||
+14
-32
@@ -73,12 +73,9 @@ async fn test_load_relay_candidates_multiple() -> Result<()> {
|
|||||||
Ok(())
|
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 transports_before = t.count_transports().await.unwrap();
|
||||||
let config_before = t
|
let config_before = t.get_config_i64(Config::LastAutorelay).await.unwrap();
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let skip_network = false; // No need to skip network, nothing is supposed to happen
|
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)
|
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();
|
.unwrap();
|
||||||
assert_eq!(relay_added, false);
|
assert_eq!(relay_added, false);
|
||||||
|
|
||||||
let config_after = t
|
let config_after = t.get_config_i64(Config::LastAutorelay).await.unwrap();
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let transports_after = t.count_transports().await.unwrap();
|
let transports_after = t.count_transports().await.unwrap();
|
||||||
|
|
||||||
assert_eq!(config_after, config_before);
|
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.
|
// already running housekeeping or relay management.
|
||||||
let _lock = t.background_task_mutex.lock().await;
|
let _lock = t.background_task_mutex.lock().await;
|
||||||
|
|
||||||
assert_automatic_relay_management_does_nothing(t).await;
|
assert_autorelay_does_nothing(t).await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -117,13 +111,10 @@ async fn test_maybe_add_additional_relays_debounce() -> Result<()> {
|
|||||||
let some_seconds_ago = time() - 10;
|
let some_seconds_ago = time() - 10;
|
||||||
|
|
||||||
// Pretend automatic relay management just ran.
|
// Pretend automatic relay management just ran.
|
||||||
t.set_config_internal(
|
t.set_config_internal(Config::LastAutorelay, Some(&some_seconds_ago.to_string()))
|
||||||
Config::LastAutomaticRelayManagement,
|
.await?;
|
||||||
Some(&some_seconds_ago.to_string()),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
assert_automatic_relay_management_does_nothing(t).await;
|
assert_autorelay_does_nothing(t).await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -132,7 +123,7 @@ async fn test_maybe_add_additional_relays_debounce() -> Result<()> {
|
|||||||
async fn test_maybe_add_additional_relays_disabled() {
|
async fn test_maybe_add_additional_relays_disabled() {
|
||||||
// By default, automatic relay management is disabled:
|
// By default, automatic relay management is disabled:
|
||||||
let t = &TestContext::new_alice().await;
|
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.
|
/// 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?;
|
let transports_count = t.count_transports().await?;
|
||||||
assert_eq!(transports_count, NUM_TRANSPORTS_TARGET - 1);
|
assert_eq!(transports_count, NUM_TRANSPORTS_TARGET - 1);
|
||||||
|
|
||||||
assert!(
|
assert!(t.get_config_bool(Config::AutorelayFinished).await?);
|
||||||
t.get_config_bool(Config::AutomaticRelayManagementFinished)
|
assert_autorelay_does_nothing(t).await;
|
||||||
.await?
|
|
||||||
);
|
|
||||||
assert_automatic_relay_management_does_nothing(t).await;
|
|
||||||
|
|
||||||
Ok(())
|
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?;
|
let relay_added = maybe_add_additional_relays_inner(t, skip_network).await?;
|
||||||
assert!(relay_added);
|
assert!(relay_added);
|
||||||
|
|
||||||
let config_after = t
|
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await?;
|
|
||||||
assert!(config_after >= now);
|
assert!(config_after >= now);
|
||||||
|
|
||||||
let transports_after = t.count_transports().await?;
|
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?;
|
let relay_added = maybe_add_additional_relays_inner(t, skip_network).await?;
|
||||||
assert!(relay_added);
|
assert!(relay_added);
|
||||||
|
|
||||||
let config_after = t
|
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await?;
|
|
||||||
assert!(config_after >= now);
|
assert!(config_after >= now);
|
||||||
|
|
||||||
let transports_after = t.count_transports().await?;
|
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);
|
assert_eq!(relay_added, false);
|
||||||
|
|
||||||
// The config is still updated:
|
// The config is still updated:
|
||||||
let config_after = t
|
let config_after = t.get_config_i64(Config::LastAutorelay).await?;
|
||||||
.get_config_i64(Config::LastAutomaticRelayManagement)
|
|
||||||
.await?;
|
|
||||||
assert!(config_after >= now);
|
assert!(config_after >= now);
|
||||||
|
|
||||||
let transports_after = t.count_transports().await?;
|
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) {
|
async fn enable_config(context: &Context) {
|
||||||
context
|
context
|
||||||
.set_config_bool(Config::AutomaticRelayManagement, true)
|
.set_config_bool(Config::Autorelay, true)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
+3
-3
@@ -353,13 +353,13 @@ pub enum Config {
|
|||||||
LastCantDecryptOutgoingMsgs,
|
LastCantDecryptOutgoingMsgs,
|
||||||
|
|
||||||
/// Timestamp of the last time automatic relay management was run
|
/// Timestamp of the last time automatic relay management was run
|
||||||
LastAutomaticRelayManagement,
|
LastAutorelay,
|
||||||
|
|
||||||
/// Whether to automatically add/remove transports
|
/// Whether to automatically add/remove transports
|
||||||
AutomaticRelayManagement,
|
Autorelay,
|
||||||
|
|
||||||
/// Whether automatic relay management successfully added the desired number of relays
|
/// 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.
|
/// Whether to avoid using IMAP IDLE even if the server supports it.
|
||||||
///
|
///
|
||||||
|
|||||||
+1
-1
@@ -749,7 +749,7 @@ mod tests {
|
|||||||
use crate::tools::SystemTime;
|
use crate::tools::SystemTime;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::automatic_relay_management::login_param_from_host;
|
use crate::autorelay::login_param_from_host;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::login_param::EnteredImapLoginParam;
|
use crate::login_param::EnteredImapLoginParam;
|
||||||
use crate::sql::update_transport_last_rcvd_timestamp;
|
use crate::sql::update_transport_last_rcvd_timestamp;
|
||||||
|
|||||||
+6
-8
@@ -1047,20 +1047,18 @@ impl Context {
|
|||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
res.insert(
|
res.insert(
|
||||||
"last_automatic_relay_management",
|
"last_autorelay",
|
||||||
self.get_config_i64(Config::LastAutomaticRelayManagement)
|
self.get_config_i64(Config::LastAutorelay)
|
||||||
.await?
|
.await?
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
res.insert(
|
res.insert(
|
||||||
"automatic_relay_management",
|
"autorelay",
|
||||||
self.get_config_bool(Config::AutomaticRelayManagement)
|
self.get_config_bool(Config::Autorelay).await?.to_string(),
|
||||||
.await?
|
|
||||||
.to_string(),
|
|
||||||
);
|
);
|
||||||
res.insert(
|
res.insert(
|
||||||
"automatic_relay_management_finished",
|
"autorelay_finished",
|
||||||
self.get_config_bool(Config::AutomaticRelayManagementFinished)
|
self.get_config_bool(Config::AutorelayFinished)
|
||||||
.await?
|
.await?
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
|
|||||||
+3
-3
@@ -53,9 +53,9 @@ impl Session {
|
|||||||
|
|
||||||
// we try to add additional relays right before going into IDLE mode,
|
// we try to add additional relays right before going into IDLE mode,
|
||||||
// because we are connected and don't have anything important to do.
|
// because we are connected and don't have anything important to do.
|
||||||
tokio::task::spawn(
|
tokio::task::spawn(crate::autorelay::maybe_add_additional_relays(
|
||||||
crate::automatic_relay_management::maybe_add_additional_relays(context.clone()),
|
context.clone(),
|
||||||
);
|
));
|
||||||
|
|
||||||
let mut handle = self.inner.idle();
|
let mut handle = self.inner.idle();
|
||||||
handle
|
handle
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ pub use events::*;
|
|||||||
|
|
||||||
mod aheader;
|
mod aheader;
|
||||||
pub mod appversions;
|
pub mod appversions;
|
||||||
mod automatic_relay_management;
|
mod autorelay;
|
||||||
pub mod blob;
|
pub mod blob;
|
||||||
pub mod calls;
|
pub mod calls;
|
||||||
pub mod chat;
|
pub mod chat;
|
||||||
|
|||||||
@@ -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 percent_encoding::{NON_ALPHANUMERIC, percent_decode_str, percent_encode};
|
||||||
use serde::Deserialize;
|
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::config::Config;
|
||||||
use crate::contact::{Contact, ContactId, Origin};
|
use crate::contact::{Contact, ContactId, Origin};
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
|||||||
Reference in New Issue
Block a user