(feat): update mtp

This commit is contained in:
Alois 2026-07-28 21:05:25 +02:00
commit 1de479ce8d
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
8 changed files with 46 additions and 180 deletions

34
Cargo.lock generated
View file

@ -1266,13 +1266,13 @@ dependencies = [
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.119", "syn 3.0.3",
] ]
[[package]] [[package]]
@ -1987,7 +1987,7 @@ dependencies = [
"libc", "libc",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"socket2 0.5.10", "socket2 0.6.5",
"system-configuration", "system-configuration",
"tokio", "tokio",
"tower-service", "tower-service",
@ -2956,7 +2956,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp" name = "mtp"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"mtp-client", "mtp-client",
"mtp-codec", "mtp-codec",
@ -2972,7 +2972,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-client" name = "mtp-client"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"mtp-codec", "mtp-codec",
"mtp-common", "mtp-common",
@ -2985,7 +2985,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-codec" name = "mtp-codec"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"base64", "base64",
"byteorder", "byteorder",
@ -2998,7 +2998,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-common" name = "mtp-common"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"quinn", "quinn",
"rustls", "rustls",
@ -3009,7 +3009,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-crypto" name = "mtp-crypto"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"base64", "base64",
"chacha20poly1305", "chacha20poly1305",
@ -3031,7 +3031,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-files" name = "mtp-files"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"mtp-crypto", "mtp-crypto",
"rand 0.10.2", "rand 0.10.2",
@ -3042,7 +3042,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-host" name = "mtp-host"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"mtp-codec", "mtp-codec",
"mtp-common", "mtp-common",
@ -3057,7 +3057,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-transport" name = "mtp-transport"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"mtp-codec", "mtp-codec",
@ -3075,7 +3075,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-type-map" name = "mtp-type-map"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_yaml", "serde_yaml",
@ -3084,7 +3084,7 @@ dependencies = [
[[package]] [[package]]
name = "mtp-webserver" name = "mtp-webserver"
version = "0.2.0" version = "0.2.0"
source = "git+https://git.methanium.net/Methanium/mtp.git#bcf8aee3716f1690f1284748ac1ff3cd22799fb0" source = "git+https://git.methanium.net/Methanium/mtp.git#590810ce59709efccd81ca04401c855be314b9c0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@ -3810,7 +3810,7 @@ dependencies = [
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls", "rustls",
"socket2 0.5.10", "socket2 0.6.5",
"thiserror 2.0.19", "thiserror 2.0.19",
"tokio", "tokio",
"tracing", "tracing",
@ -3851,7 +3851,7 @@ dependencies = [
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"once_cell", "once_cell",
"socket2 0.5.10", "socket2 0.6.5",
"tracing", "tracing",
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
@ -4835,7 +4835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.4", "getrandom 0.4.3",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.61.2", "windows-sys 0.61.2",

View file

@ -25,7 +25,6 @@ pub struct ClientConnection {
sender: Arc<RwLock<Option<Arc<Sender>>>>, sender: Arc<RwLock<Option<Arc<Sender>>>>,
receiver: Receiver, receiver: Receiver,
connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>, connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
pub ping: Arc<RwLock<i64>>,
pub connection_id: Uuid, pub connection_id: Uuid,
shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>, shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>,
pub waiting_tasks: pub waiting_tasks:
@ -38,7 +37,6 @@ impl ClientConnection {
sender: Arc<RwLock<Option<Arc<Sender>>>>, sender: Arc<RwLock<Option<Arc<Sender>>>>,
receiver: Receiver, receiver: Receiver,
connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>, connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
ping: Arc<RwLock<i64>>,
connection_id: Uuid, connection_id: Uuid,
shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>, shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>,
waiting_tasks: DashMap< waiting_tasks: DashMap<
@ -51,7 +49,6 @@ impl ClientConnection {
sender, sender,
receiver, receiver,
connection_loop_handle, connection_loop_handle,
ping,
connection_id, connection_id,
shutdown_tx, shutdown_tx,
waiting_tasks, waiting_tasks,
@ -96,34 +93,11 @@ impl ClientConnection {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Message Handling // Message Handling
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
async fn handle_ping(self: Arc<Self>, cv: CommunicationValue) {
// Update our ping if provided
if let DataValue::SignedNumber(last_ping) = cv.get_data(DataType::LastPing) {
let current = now_millis_i64();
let mut ping_guard = self.ping.write().await;
*ping_guard = current - *last_ping as i64;
}
// Send pong response
let response = CommunicationValue::new(CommunicationType::Pong)
.with_id(cv.get_id())
.add_typed_default(DataType::PingIota, DataValue::SignedNumber(0));
self.send_message(&response).await;
}
pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) { pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) {
if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_in!(&cv); log_cv_in!(&cv);
}
let _msg_id = cv.get_id(); let _msg_id = cv.get_id();
if cv.is_type(CommunicationType::Ping) {
self.handle_ping(cv).await;
return;
}
if cv.is_type(CommunicationType::Challenge) { if cv.is_type(CommunicationType::Challenge) {
self.handle_challenge(&cv).await; self.handle_challenge(&cv).await;
return; return;
@ -566,9 +540,7 @@ impl ClientConnection {
let sender_clone = Arc::clone(sender); let sender_clone = Arc::clone(sender);
drop(sender_guard); drop(sender_guard);
if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_out!(&cv); log_cv_out!(&cv);
}
if let Err(e) = sender_clone.send(cv).await { if let Err(e) = sender_clone.send(cv).await {
return Err(e.to_string()); return Err(e.to_string());

View file

@ -30,7 +30,6 @@ pub struct CommunityConnection {
challenged: Arc<RwLock<bool>>, challenged: Arc<RwLock<bool>>,
challenge: Arc<RwLock<String>>, challenge: Arc<RwLock<String>>,
auth: Arc<RwLock<Option<AuthUser>>>, auth: Arc<RwLock<Option<AuthUser>>>,
pub ping: Arc<RwLock<i64>>,
} }
impl CommunityConnection { impl CommunityConnection {
pub fn new( pub fn new(
@ -47,7 +46,6 @@ impl CommunityConnection {
challenged: Arc::new(RwLock::new(false)), challenged: Arc::new(RwLock::new(false)),
challenge: Arc::new(RwLock::new(String::new())), challenge: Arc::new(RwLock::new(String::new())),
auth: Arc::new(RwLock::new(None)), auth: Arc::new(RwLock::new(None)),
ping: Arc::new(RwLock::new(-1)),
}) })
} }
pub async fn send_message(&self, message: &CommunicationValue) { pub async fn send_message(&self, message: &CommunicationValue) {
@ -84,11 +82,6 @@ impl CommunityConnection {
return; return;
} }
if cv.is_type(CommunicationType::Ping) {
self.handle_ping(cv).await;
return;
}
if cv.is_type(CommunicationType::ClientChanged) { if cv.is_type(CommunicationType::ClientChanged) {
//self.handle_client_changed(cv).await; //self.handle_client_changed(cv).await;
return; return;
@ -381,16 +374,4 @@ impl CommunityConnection {
} }
} }
async fn handle_ping(&self, cv: CommunicationValue) {
if let Some(last_ping) = cv.get_data(DataType::LastPing) {
if let Ok(ping_val) = last_ping.to_string().parse::<i64>() {
let mut ping_guard = self.ping.write().await;
*ping_guard = ping_val;
}
}
let response = CommunicationValue::new(CommunicationType::Pong).with_id(cv.get_id());
self.send_message(&response).await;
}
} }

View file

@ -11,7 +11,6 @@ use iota_storage::users::user_manager;
use iota_storage::util::config_util::{self}; use iota_storage::util::config_util::{self};
use mtp::codec::{CommunicationType, CommunicationValue}; use mtp::codec::{CommunicationType, CommunicationValue};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::daemon_state::{ShutdownReason, StartupPhase}; use crate::daemon_state::{ShutdownReason, StartupPhase};
@ -295,22 +294,4 @@ impl CommandRouter {
} }
} }
} }
pub async fn ping(&self, seconds: u64) -> Result<String, String> {
let response = self
.services
.omikron
.await_response(
&CommunicationValue::new(CommunicationType::Ping),
Duration::from_secs(seconds),
)
.await;
match response {
Ok(value) => {
log!("{}", iota_logger::format_cv(&value));
Ok("Ping response received".into())
}
Err(error) => Err(format!("Ping error: {error:?}")),
}
}
} }

@ -1 +1 @@
Subproject commit 594646ac39d986f0787aa614a99d580035a67318 Subproject commit f430cd358b3d07a4cfd6982eb8917fec80c24a7d

View file

@ -1,7 +1,6 @@
pub mod client; pub mod client;
pub mod omega_discovery; pub mod omega_discovery;
pub mod omikron_connection; pub mod omikron_connection;
pub mod ping_pong_task;
pub mod user_ops; pub mod user_ops;
pub use client::{OmikronClient, OmikronError, OmikronStartupError}; pub use client::{OmikronClient, OmikronError, OmikronStartupError};

View file

@ -11,7 +11,6 @@ use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use mtp::crypto::{Keyring, PublicKeyBundle}; use mtp::crypto::{Keyring, PublicKeyBundle};
use std::env; use std::env;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use tokio::sync::{Mutex, RwLock, Semaphore, oneshot, watch}; use tokio::sync::{Mutex, RwLock, Semaphore, oneshot, watch};
@ -110,10 +109,10 @@ const OMIKRON_PUBLIC_KEY_PATH: &str = "omikron.mpkb";
const RECONNECT_DELAY: Duration = Duration::from_secs(5); const RECONNECT_DELAY: Duration = Duration::from_secs(5);
const MAX_RECONNECT_DELAY: Duration = Duration::from_secs(300); const MAX_RECONNECT_DELAY: Duration = Duration::from_secs(300);
const CONNECTION_TIMEOUT: Duration = Duration::from_secs(10); const CONNECTION_TIMEOUT: Duration = Duration::from_secs(10);
const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); const MAINTENANCE_INTERVAL: Duration = Duration::from_secs(5);
const TASK_CLEANUP_INTERVAL: Duration = Duration::from_secs(60); const TASK_CLEANUP_INTERVAL: Duration = Duration::from_secs(60);
const TASK_MAX_AGE: Duration = Duration::from_secs(60); const TASK_MAX_AGE: Duration = Duration::from_secs(60);
const MAX_MISSED_PONGS: u32 = 3; const MAX_MISSED_PINGS: usize = 3;
const MAX_CONCURRENT_HANDLERS: usize = 20; const MAX_CONCURRENT_HANDLERS: usize = 20;
// ============================================================================ // ============================================================================
@ -168,14 +167,13 @@ pub struct OmikronConnection {
sender: Arc<RwLock<Option<Arc<Sender>>>>, sender: Arc<RwLock<Option<Arc<Sender>>>>,
connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>, connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
pub last_ping: Arc<Mutex<i64>>, pub last_ping: Arc<Mutex<i64>>,
heartbeat_handle: Arc<Mutex<Option<JoinHandle<()>>>>, maintenance_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
pub connection_id: Uuid, pub connection_id: Uuid,
shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>, shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>,
reconnect_on_close: Arc<RwLock<bool>>, reconnect_on_close: Arc<RwLock<bool>>,
auth_failure: Arc<RwLock<Option<String>>>, auth_failure: Arc<RwLock<Option<String>>>,
pub app_challenges: Arc<DashMap<u64, String>>, pub app_challenges: Arc<DashMap<u64, String>>,
pub app_sessions: Arc<DashMap<u64, (i64, String)>>, pub app_sessions: Arc<DashMap<u64, (i64, String)>>,
pub(crate) missed_pongs: Arc<AtomicU32>,
handler_semaphore: Arc<Semaphore>, handler_semaphore: Arc<Semaphore>,
cancellation: CancellationToken, cancellation: CancellationToken,
pub(crate) active_tasks: Arc<DashSet<String>>, pub(crate) active_tasks: Arc<DashSet<String>>,
@ -201,14 +199,13 @@ impl OmikronConnection {
sender: Arc::new(RwLock::new(None)), sender: Arc::new(RwLock::new(None)),
connection_loop_handle: Arc::new(Mutex::new(None)), connection_loop_handle: Arc::new(Mutex::new(None)),
last_ping: Arc::new(Mutex::new(-1)), last_ping: Arc::new(Mutex::new(-1)),
heartbeat_handle: Arc::new(Mutex::new(None)), maintenance_handle: Arc::new(Mutex::new(None)),
connection_id: Uuid::new_v4(), connection_id: Uuid::new_v4(),
shutdown_tx: Arc::new(Mutex::new(Some(shutdown_tx))), shutdown_tx: Arc::new(Mutex::new(Some(shutdown_tx))),
reconnect_on_close: Arc::new(RwLock::new(true)), reconnect_on_close: Arc::new(RwLock::new(true)),
auth_failure: Arc::new(RwLock::new(None)), auth_failure: Arc::new(RwLock::new(None)),
app_challenges: Arc::new(DashMap::new()), app_challenges: Arc::new(DashMap::new()),
app_sessions: Arc::new(DashMap::new()), app_sessions: Arc::new(DashMap::new()),
missed_pongs: Arc::new(AtomicU32::new(0)),
handler_semaphore: Arc::new(Semaphore::new(MAX_CONCURRENT_HANDLERS)), handler_semaphore: Arc::new(Semaphore::new(MAX_CONCURRENT_HANDLERS)),
cancellation, cancellation,
active_tasks, active_tasks,
@ -267,7 +264,7 @@ impl OmikronConnection {
handle.abort(); handle.abort();
} }
if let Some(handle) = self.heartbeat_handle.lock().await.take() { if let Some(handle) = self.maintenance_handle.lock().await.take() {
handle.abort(); handle.abort();
} }
@ -363,7 +360,9 @@ impl OmikronConnection {
persistent_stream_max_retries: 5, persistent_stream_max_retries: 5,
persistent_stream_retry_backoff: Duration::from_secs(5), persistent_stream_retry_backoff: Duration::from_secs(5),
max_frames_per_stream: None, max_frames_per_stream: None,
}); })
.with_ping_interval(MAINTENANCE_INTERVAL)
.with_max_missed_pings(MAX_MISSED_PINGS);
let connection = match Client::auth_connect_or_register( let connection = match Client::auth_connect_or_register(
client_config, client_config,
@ -402,18 +401,18 @@ impl OmikronConnection {
// Start read loop // Start read loop
let connection = Arc::new(connection); let connection = Arc::new(connection);
let read_self = self.clone(); let read_self = self.clone();
let read_connection = connection.clone();
let read_handle = tokio::spawn(async move { let read_handle = tokio::spawn(async move {
read_self.read_loop(connection).await; read_self.read_loop(read_connection).await;
}); });
log_t!("omikron_authenticated"); log_t!("omikron_authenticated");
// Start heartbeat let maintenance_self = self.clone();
let heartbeat_self = self.clone(); let maintenance_handle = tokio::spawn(async move {
let heartbeat_handle = tokio::spawn(async move { maintenance_self.maintenance_loop(connection).await;
heartbeat_self.heartbeat_loop().await;
}); });
*self.heartbeat_handle.lock().await = Some(heartbeat_handle); *self.maintenance_handle.lock().await = Some(maintenance_handle);
{ {
self.active_tasks.insert("Omikron Listener".to_string()); self.active_tasks.insert("Omikron Listener".to_string());
@ -427,7 +426,7 @@ impl OmikronConnection {
self.active_tasks.remove("Omikron Listener"); self.active_tasks.remove("Omikron Listener");
} }
if let Some(handle) = self.heartbeat_handle.lock().await.take() { if let Some(handle) = self.maintenance_handle.lock().await.take() {
handle.abort(); handle.abort();
} }
@ -589,7 +588,7 @@ impl OmikronConnection {
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Read Loop & Heartbeat // Read Loop & Maintenance
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
async fn read_loop(self: Arc<Self>, connection: Arc<MTPConnection>) { async fn read_loop(self: Arc<Self>, connection: Arc<MTPConnection>) {
@ -603,11 +602,6 @@ impl OmikronConnection {
continue; continue;
} }
} }
if cv.is_type(CommunicationType::Pong) {
self.handle_pong(&cv).await;
continue;
}
let permit = self.handler_semaphore.clone().acquire_owned().await; let permit = self.handler_semaphore.clone().acquire_owned().await;
let self_clone = self.clone(); let self_clone = self.clone();
tokio::spawn(async move { tokio::spawn(async move {
@ -635,9 +629,9 @@ impl OmikronConnection {
} }
} }
async fn heartbeat_loop(self: Arc<Self>) { async fn maintenance_loop(self: Arc<Self>, connection: Arc<MTPConnection>) {
loop { loop {
sleep(HEARTBEAT_INTERVAL).await; sleep(MAINTENANCE_INTERVAL).await;
if !self.state.read().await.is_connected() { if !self.state.read().await.is_connected() {
break; break;
@ -651,19 +645,13 @@ impl OmikronConnection {
break; break;
} }
if self.missed_pongs.load(Ordering::Relaxed) > MAX_MISSED_PONGS { if let Some(ping) = connection.get_ping() {
log!( let ping_ms = ping.as_millis() as i64;
"Connection appears dead ({} consecutive missed pongs), closing sender", *self.last_ping.lock().await = ping_ms;
self.missed_pongs.load(Ordering::Relaxed) self.app.lock().unwrap().push_ping_val(ping_ms as f64);
);
if let Some(sender) = self.sender.read().await.as_ref() {
sender.close().await;
}
break;
} }
self.flush_pending_chat_secret_forwards().await; self.flush_pending_chat_secret_forwards().await;
self.send_ping().await;
} }
} }
@ -854,9 +842,7 @@ impl OmikronConnection {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) { pub async fn handle_message(self: Arc<Self>, cv: CommunicationValue) {
if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_in!(&cv); log_cv_in!(&cv);
}
let msg_id = cv.get_id(); let msg_id = cv.get_id();
@ -866,11 +852,6 @@ impl OmikronConnection {
} }
} }
if cv.is_type(CommunicationType::Pong) {
self.handle_pong(&cv).await;
return;
}
self.clone().handle_message_impl(cv).await; self.clone().handle_message_impl(cv).await;
} }
@ -1804,9 +1785,7 @@ impl OmikronConnection {
let sender_clone = Arc::clone(sender); let sender_clone = Arc::clone(sender);
drop(sender_guard); drop(sender_guard);
if !cv.is_type(CommunicationType::Ping) && !cv.is_type(CommunicationType::Pong) {
log_cv_out!(&cv); log_cv_out!(&cv);
}
if let Err(e) = sender_clone.send(cv).await { if let Err(e) = sender_clone.send(cv).await {
self.fail_all_waiting_tasks(format!( self.fail_all_waiting_tasks(format!(
@ -2117,14 +2096,13 @@ impl OmikronClient for OmikronConnection {
sender: self.sender.clone(), sender: self.sender.clone(),
connection_loop_handle: self.connection_loop_handle.clone(), connection_loop_handle: self.connection_loop_handle.clone(),
last_ping: self.last_ping.clone(), last_ping: self.last_ping.clone(),
heartbeat_handle: self.heartbeat_handle.clone(), maintenance_handle: self.maintenance_handle.clone(),
connection_id: self.connection_id, connection_id: self.connection_id,
shutdown_tx: self.shutdown_tx.clone(), shutdown_tx: self.shutdown_tx.clone(),
reconnect_on_close: self.reconnect_on_close.clone(), reconnect_on_close: self.reconnect_on_close.clone(),
auth_failure: self.auth_failure.clone(), auth_failure: self.auth_failure.clone(),
app_challenges: self.app_challenges.clone(), app_challenges: self.app_challenges.clone(),
app_sessions: self.app_sessions.clone(), app_sessions: self.app_sessions.clone(),
missed_pongs: self.missed_pongs.clone(),
handler_semaphore: self.handler_semaphore.clone(), handler_semaphore: self.handler_semaphore.clone(),
cancellation: self.cancellation.clone(), cancellation: self.cancellation.clone(),
active_tasks: self.active_tasks.clone(), active_tasks: self.active_tasks.clone(),
@ -2141,14 +2119,13 @@ impl OmikronClient for OmikronConnection {
sender: self.sender.clone(), sender: self.sender.clone(),
connection_loop_handle: self.connection_loop_handle.clone(), connection_loop_handle: self.connection_loop_handle.clone(),
last_ping: self.last_ping.clone(), last_ping: self.last_ping.clone(),
heartbeat_handle: self.heartbeat_handle.clone(), maintenance_handle: self.maintenance_handle.clone(),
connection_id: self.connection_id, connection_id: self.connection_id,
shutdown_tx: self.shutdown_tx.clone(), shutdown_tx: self.shutdown_tx.clone(),
reconnect_on_close: self.reconnect_on_close.clone(), reconnect_on_close: self.reconnect_on_close.clone(),
auth_failure: self.auth_failure.clone(), auth_failure: self.auth_failure.clone(),
app_challenges: self.app_challenges.clone(), app_challenges: self.app_challenges.clone(),
app_sessions: self.app_sessions.clone(), app_sessions: self.app_sessions.clone(),
missed_pongs: self.missed_pongs.clone(),
handler_semaphore: self.handler_semaphore.clone(), handler_semaphore: self.handler_semaphore.clone(),
cancellation: self.cancellation.clone(), cancellation: self.cancellation.clone(),
active_tasks: self.active_tasks.clone(), active_tasks: self.active_tasks.clone(),

View file

@ -1,44 +0,0 @@
use crate::omikron_connection::OmikronConnection;
use dashmap::DashMap;
use mtp::codec::{CommunicationType, CommunicationValue, DataType, DataValue};
use std::sync::LazyLock;
use std::sync::atomic::Ordering;
use std::time::Instant;
use tokio::time::Duration;
static PING_TIMES: LazyLock<DashMap<u32, Instant>> = LazyLock::new(|| DashMap::new());
impl OmikronConnection {
pub async fn send_ping(&self) {
let id = rand::random();
PING_TIMES.insert(id, Instant::now());
PING_TIMES.retain(|_, v| v.elapsed() < Duration::from_secs(30));
self.missed_pongs.fetch_add(1, Ordering::Relaxed);
let ping_message = CommunicationValue::new(CommunicationType::Ping)
.with_id(id)
.add_typed_default(
DataType::LastPing,
DataValue::Array(vec![DataValue::SignedNumber(
*self.last_ping.lock().await as i128,
)]),
);
let _ = self.send_message(&ping_message).await;
}
pub async fn handle_pong(&self, cv: &CommunicationValue) {
self.missed_pongs.store(0, Ordering::Relaxed);
let id = cv.get_id();
if let Some((_, send_time)) = PING_TIMES.remove(&id) {
let ping_ms = Instant::now().duration_since(send_time).as_millis() as i64;
*self.last_ping.lock().await = ping_ms;
self.app.lock().unwrap().push_ping_val(ping_ms as f64);
}
}
}