diff --git a/crates/udp/src/common.rs b/crates/udp/src/common.rs index 8cc322c..6504f06 100644 --- a/crates/udp/src/common.rs +++ b/crates/udp/src/common.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::hash::Hash; use std::io::Write; +use std::mem::size_of; use std::net::{SocketAddr, SocketAddrV4}; use std::sync::atomic::AtomicUsize; use std::sync::Arc; @@ -101,6 +102,15 @@ pub struct ConnectedResponseWithAddr { pub addr: CanonicalSocketAddr, } +impl ConnectedResponseWithAddr { + pub fn estimated_max_size(config: &Config) -> usize { + size_of::() + + config.protocol.max_response_peers + * (size_of::>() + + size_of::>()) + } +} + pub struct Recycler; impl thingbuf::Recycle for Recycler { diff --git a/crates/udp/src/lib.rs b/crates/udp/src/lib.rs index 6658b37..c9871ba 100644 --- a/crates/udp/src/lib.rs +++ b/crates/udp/src/lib.rs @@ -3,6 +3,7 @@ pub mod config; pub mod workers; use std::collections::BTreeMap; +use std::mem::size_of; use std::thread::Builder; use std::time::Duration; @@ -15,7 +16,7 @@ use aquatic_common::access_list::update_access_list; #[cfg(feature = "cpu-pinning")] use aquatic_common::cpu_pinning::{pin_current_if_configured_to, WorkerIndex}; use aquatic_common::privileges::PrivilegeDropper; -use aquatic_common::{PanicSentinelWatcher, ServerStartInstant}; +use aquatic_common::{CanonicalSocketAddr, PanicSentinelWatcher, ServerStartInstant}; use common::{ ConnectedRequestSender, ConnectedResponseSender, Recycler, SocketWorkerIndex, State, @@ -24,12 +25,19 @@ use common::{ use config::Config; use workers::socket::ConnectionValidator; +use crate::common::{ConnectedRequest, ConnectedResponseWithAddr}; + pub const APP_NAME: &str = "aquatic_udp: UDP BitTorrent tracker"; pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION"); pub fn run(config: Config) -> ::anyhow::Result<()> { let mut signals = Signals::new([SIGUSR1, SIGTERM])?; + ::log::info!( + "Estimated max channel memory use: {:.02} MB", + est_max_total_channel_memory(&config) + ); + let state = State::new(config.swarm_workers); let connection_validator = ConnectionValidator::new(&config)?; let (sentinel_watcher, sentinel) = PanicSentinelWatcher::create_with_sentinel(); @@ -206,3 +214,16 @@ pub fn run(config: Config) -> ::anyhow::Result<()> { Ok(()) } + +fn est_max_total_channel_memory(config: &Config) -> f64 { + let request_channel_max_size = config.swarm_workers + * config.worker_channel_size + * (size_of::() + + size_of::() + + size_of::()); + let response_channel_max_size = config.socket_workers + * config.worker_channel_size + * ConnectedResponseWithAddr::estimated_max_size(&config); + + (request_channel_max_size as u64 + response_channel_max_size as u64) as f64 / (1024.0 * 1024.0) +}