diff --git a/Cargo.lock b/Cargo.lock index 62ea631..50b5ece 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,11 +224,9 @@ dependencies = [ "aquatic_cli_helpers", "aquatic_common", "aquatic_udp_protocol", - "crossbeam-channel", "hashbrown 0.11.2", "mimalloc", "mio", - "parking_lot", "quickcheck", "quickcheck_macros", "rand", diff --git a/aquatic_udp_load_test/Cargo.toml b/aquatic_udp_load_test/Cargo.toml index d77977b..52d39fa 100644 --- a/aquatic_udp_load_test/Cargo.toml +++ b/aquatic_udp_load_test/Cargo.toml @@ -17,11 +17,9 @@ anyhow = "1" aquatic_cli_helpers = "0.1.0" aquatic_common = "0.1.0" aquatic_udp_protocol = "0.1.0" -crossbeam-channel = "0.5" hashbrown = "0.11.2" mimalloc = { version = "0.1", default-features = false } mio = { version = "0.7", features = ["udp", "os-poll", "os-util"] } -parking_lot = "0.11" rand = { version = "0.8", features = ["small_rng"] } rand_distr = "0.4" serde = { version = "1", features = ["derive"] } diff --git a/aquatic_udp_load_test/src/common.rs b/aquatic_udp_load_test/src/common.rs index fe81667..276c324 100644 --- a/aquatic_udp_load_test/src/common.rs +++ b/aquatic_udp_load_test/src/common.rs @@ -1,133 +1,12 @@ -use std::net::SocketAddr; use std::sync::{atomic::AtomicUsize, Arc}; -use aquatic_cli_helpers::LogLevel; -#[cfg(feature = "cpu-pinning")] -use aquatic_common::cpu_pinning::CpuPinningConfig; use hashbrown::HashMap; -use serde::{Deserialize, Serialize}; use aquatic_udp_protocol::*; #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] pub struct ThreadId(pub u8); -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(default)] -pub struct Config { - /// Server address - /// - /// If you want to send IPv4 requests to a IPv4+IPv6 tracker, put an IPv4 - /// address here. - pub server_address: SocketAddr, - pub log_level: LogLevel, - pub workers: u8, - /// Run duration (quit and generate report after this many seconds) - pub duration: usize, - pub network: NetworkConfig, - pub handler: HandlerConfig, - #[cfg(feature = "cpu-pinning")] - pub cpu_pinning: CpuPinningConfig, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(default)] -pub struct NetworkConfig { - /// True means bind to one localhost IP per socket. - /// - /// The point of multiple IPs is to cause a better distribution - /// of requests to servers with SO_REUSEPORT option. - /// - /// Setting this to true can cause issues on macOS. - pub multiple_client_ipv4s: bool, - /// Number of first client port - pub first_port: u16, - /// Socket worker poll timeout in microseconds - pub poll_timeout: u64, - /// Socket worker polling event number - pub poll_event_capacity: usize, - /// Size of socket recv buffer. Use 0 for OS default. - /// - /// This setting can have a big impact on dropped packages. It might - /// require changing system defaults. Some examples of commands to set - /// recommended values for different operating systems: - /// - /// macOS: - /// $ sudo sysctl net.inet.udp.recvspace=6000000 - /// $ sudo sysctl net.inet.udp.maxdgram=500000 # Not necessary, but recommended - /// $ sudo sysctl kern.ipc.maxsockbuf=8388608 # Not necessary, but recommended - /// - /// Linux: - /// $ sudo sysctl -w net.core.rmem_max=104857600 - /// $ sudo sysctl -w net.core.rmem_default=104857600 - pub recv_buffer: usize, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(default)] -pub struct HandlerConfig { - /// Number of torrents to simulate - pub number_of_torrents: usize, - /// Maximum number of torrents to ask about in scrape requests - pub scrape_max_torrents: usize, - /// Probability that a generated request is a connect request as part - /// of sum of the various weight arguments. - pub weight_connect: usize, - /// Probability that a generated request is a announce request, as part - /// of sum of the various weight arguments. - pub weight_announce: usize, - /// Probability that a generated request is a scrape request, as part - /// of sum of the various weight arguments. - pub weight_scrape: usize, - /// Pareto shape - /// - /// Fake peers choose torrents according to Pareto distribution. - pub torrent_selection_pareto_shape: f64, - /// Probability that a generated peer is a seeder - pub peer_seeder_probability: f64, -} - -impl Default for Config { - fn default() -> Self { - Self { - server_address: "127.0.0.1:3000".parse().unwrap(), - log_level: LogLevel::Error, - workers: 1, - duration: 0, - network: NetworkConfig::default(), - handler: HandlerConfig::default(), - #[cfg(feature = "cpu-pinning")] - cpu_pinning: CpuPinningConfig::default_for_load_test(), - } - } -} - -impl Default for NetworkConfig { - fn default() -> Self { - Self { - multiple_client_ipv4s: true, - first_port: 45_000, - poll_timeout: 276, - poll_event_capacity: 2_877, - recv_buffer: 6_000_000, - } - } -} - -impl Default for HandlerConfig { - fn default() -> Self { - Self { - number_of_torrents: 10_000, - peer_seeder_probability: 0.25, - scrape_max_torrents: 50, - weight_connect: 0, - weight_announce: 5, - weight_scrape: 1, - torrent_selection_pareto_shape: 2.0, - } - } -} - #[derive(PartialEq, Eq, Clone)] pub struct TorrentPeer { pub info_hash: InfoHash, diff --git a/aquatic_udp_load_test/src/config.rs b/aquatic_udp_load_test/src/config.rs new file mode 100644 index 0000000..458adc4 --- /dev/null +++ b/aquatic_udp_load_test/src/config.rs @@ -0,0 +1,124 @@ +use std::net::SocketAddr; + +use serde::{Deserialize, Serialize}; + +use aquatic_cli_helpers::LogLevel; +#[cfg(feature = "cpu-pinning")] +use aquatic_common::cpu_pinning::CpuPinningConfig; + + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] +pub struct Config { + /// Server address + /// + /// If you want to send IPv4 requests to a IPv4+IPv6 tracker, put an IPv4 + /// address here. + pub server_address: SocketAddr, + pub log_level: LogLevel, + pub workers: u8, + /// Run duration (quit and generate report after this many seconds) + pub duration: usize, + pub network: NetworkConfig, + pub handler: HandlerConfig, + #[cfg(feature = "cpu-pinning")] + pub cpu_pinning: CpuPinningConfig, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] +pub struct NetworkConfig { + /// True means bind to one localhost IP per socket. + /// + /// The point of multiple IPs is to cause a better distribution + /// of requests to servers with SO_REUSEPORT option. + /// + /// Setting this to true can cause issues on macOS. + pub multiple_client_ipv4s: bool, + /// Number of first client port + pub first_port: u16, + /// Socket worker poll timeout in microseconds + pub poll_timeout: u64, + /// Socket worker polling event number + pub poll_event_capacity: usize, + /// Size of socket recv buffer. Use 0 for OS default. + /// + /// This setting can have a big impact on dropped packages. It might + /// require changing system defaults. Some examples of commands to set + /// recommended values for different operating systems: + /// + /// macOS: + /// $ sudo sysctl net.inet.udp.recvspace=6000000 + /// $ sudo sysctl net.inet.udp.maxdgram=500000 # Not necessary, but recommended + /// $ sudo sysctl kern.ipc.maxsockbuf=8388608 # Not necessary, but recommended + /// + /// Linux: + /// $ sudo sysctl -w net.core.rmem_max=104857600 + /// $ sudo sysctl -w net.core.rmem_default=104857600 + pub recv_buffer: usize, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] +pub struct HandlerConfig { + /// Number of torrents to simulate + pub number_of_torrents: usize, + /// Maximum number of torrents to ask about in scrape requests + pub scrape_max_torrents: usize, + /// Probability that a generated request is a connect request as part + /// of sum of the various weight arguments. + pub weight_connect: usize, + /// Probability that a generated request is a announce request, as part + /// of sum of the various weight arguments. + pub weight_announce: usize, + /// Probability that a generated request is a scrape request, as part + /// of sum of the various weight arguments. + pub weight_scrape: usize, + /// Pareto shape + /// + /// Fake peers choose torrents according to Pareto distribution. + pub torrent_selection_pareto_shape: f64, + /// Probability that a generated peer is a seeder + pub peer_seeder_probability: f64, +} + +impl Default for Config { + fn default() -> Self { + Self { + server_address: "127.0.0.1:3000".parse().unwrap(), + log_level: LogLevel::Error, + workers: 1, + duration: 0, + network: NetworkConfig::default(), + handler: HandlerConfig::default(), + #[cfg(feature = "cpu-pinning")] + cpu_pinning: CpuPinningConfig::default_for_load_test(), + } + } +} + +impl Default for NetworkConfig { + fn default() -> Self { + Self { + multiple_client_ipv4s: true, + first_port: 45_000, + poll_timeout: 276, + poll_event_capacity: 2_877, + recv_buffer: 6_000_000, + } + } +} + +impl Default for HandlerConfig { + fn default() -> Self { + Self { + number_of_torrents: 10_000, + peer_seeder_probability: 0.25, + scrape_max_torrents: 50, + weight_connect: 0, + weight_announce: 5, + weight_scrape: 1, + torrent_selection_pareto_shape: 2.0, + } + } +} \ No newline at end of file diff --git a/aquatic_udp_load_test/src/handler.rs b/aquatic_udp_load_test/src/handler.rs index cc98c27..fe0a188 100644 --- a/aquatic_udp_load_test/src/handler.rs +++ b/aquatic_udp_load_test/src/handler.rs @@ -6,6 +6,7 @@ use rand_distr::Pareto; use aquatic_udp_protocol::*; +use crate::config::Config; use crate::common::*; use crate::utils::*; diff --git a/aquatic_udp_load_test/src/main.rs b/aquatic_udp_load_test/src/main.rs index 9bd4dc4..3a7651c 100644 --- a/aquatic_udp_load_test/src/main.rs +++ b/aquatic_udp_load_test/src/main.rs @@ -8,11 +8,13 @@ use aquatic_common::cpu_pinning::{pin_current_if_configured_to, WorkerIndex}; use rand_distr::Pareto; mod common; +mod config; mod handler; mod network; mod utils; use common::*; +use config::Config; use network::*; use utils::*; diff --git a/aquatic_udp_load_test/src/network.rs b/aquatic_udp_load_test/src/network.rs index a74e28c..e89df1f 100644 --- a/aquatic_udp_load_test/src/network.rs +++ b/aquatic_udp_load_test/src/network.rs @@ -10,6 +10,7 @@ use socket2::{Domain, Protocol, Socket, Type}; use aquatic_udp_protocol::*; +use crate::config::Config; use crate::{common::*, handler::process_response, utils::*}; const MAX_PACKET_SIZE: usize = 4096; diff --git a/aquatic_udp_load_test/src/utils.rs b/aquatic_udp_load_test/src/utils.rs index b2ee9c8..f9ee26e 100644 --- a/aquatic_udp_load_test/src/utils.rs +++ b/aquatic_udp_load_test/src/utils.rs @@ -5,6 +5,7 @@ use rand_distr::Pareto; use aquatic_udp_protocol::*; +use crate::config::Config; use crate::common::*; pub fn create_torrent_peer(