mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
Merge pull request #28 from greatest-ape/http-load-test-fixes
Name glommio worker threads; improve http load test
This commit is contained in:
commit
0886c71595
11 changed files with 76 additions and 34 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -139,6 +139,7 @@ dependencies = [
|
|||
"futures-lite",
|
||||
"glommio",
|
||||
"hashbrown 0.11.2",
|
||||
"log",
|
||||
"mimalloc",
|
||||
"quickcheck",
|
||||
"quickcheck_macros",
|
||||
|
|
|
|||
5
TODO.md
5
TODO.md
|
|
@ -39,8 +39,9 @@
|
|||
* consider better error type for request parsing, so that better error
|
||||
messages can be sent back (e.g., "full scrapes are not supported")
|
||||
|
||||
* http and ws load tests
|
||||
* add config key 'connection_open_interval_ms', default to 1000
|
||||
* aquatic_ws
|
||||
* glommio
|
||||
* fix memory leak / huge growth
|
||||
|
||||
## Less important
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
#[cfg(feature = "cpu-pinning")]
|
||||
use aquatic_common::cpu_pinning::{pin_current_if_configured_to, WorkerIndex};
|
||||
use aquatic_common::{
|
||||
access_list::update_access_list, privileges::drop_privileges_after_socket_binding,
|
||||
};
|
||||
use common::{State, TlsConfig};
|
||||
use glommio::{channels::channel_mesh::MeshBuilder, prelude::*};
|
||||
use signal_hook::{consts::SIGUSR1, iterator::Signals};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::BufReader,
|
||||
sync::{atomic::AtomicUsize, Arc},
|
||||
};
|
||||
use aquatic_common::{
|
||||
access_list::update_access_list,
|
||||
privileges::drop_privileges_after_socket_binding,
|
||||
};
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
use aquatic_common::cpu_pinning::{pin_current_if_configured_to, WorkerIndex};
|
||||
use common::{State, TlsConfig};
|
||||
use glommio::{channels::channel_mesh::MeshBuilder, prelude::*};
|
||||
use signal_hook::{consts::SIGUSR1, iterator::Signals};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
|
|
@ -77,7 +76,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
let num_bound_sockets = num_bound_sockets.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("socket");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
|
|
@ -105,7 +106,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let request_mesh_builder = request_mesh_builder.clone();
|
||||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("request");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ aquatic_http_protocol = "0.1.0"
|
|||
futures-lite = "1"
|
||||
hashbrown = "0.11.2"
|
||||
glommio = { git = "https://github.com/DataDog/glommio.git", rev = "4e6b14772da2f4325271fbcf12d24cf91ed466e5" }
|
||||
log = "0.4"
|
||||
mimalloc = { version = "0.1", default-features = false }
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
rand_distr = "0.4"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,13 @@ pub struct Config {
|
|||
pub server_address: SocketAddr,
|
||||
pub log_level: LogLevel,
|
||||
pub num_workers: usize,
|
||||
/// Maximum number of connections to keep open
|
||||
pub num_connections: usize,
|
||||
/// How often to check if num_connections connections are open, and
|
||||
/// open a new one otherwise. A value of 0 means that connections are
|
||||
/// opened as quickly as possible, which is useful when the tracker
|
||||
/// doesn't keep connections alive.
|
||||
pub connection_creation_interval_ms: u64,
|
||||
pub duration: usize,
|
||||
pub torrents: TorrentConfig,
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
|
|
@ -46,7 +52,8 @@ impl Default for Config {
|
|||
server_address: "127.0.0.1:3000".parse().unwrap(),
|
||||
log_level: LogLevel::Error,
|
||||
num_workers: 1,
|
||||
num_connections: 8,
|
||||
num_connections: 128,
|
||||
connection_creation_interval_ms: 10,
|
||||
duration: 0,
|
||||
torrents: TorrentConfig::default(),
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
|
|
|
|||
|
|
@ -24,14 +24,36 @@ pub async fn run_socket_thread(
|
|||
let config = Rc::new(config);
|
||||
let num_active_connections = Rc::new(RefCell::new(0usize));
|
||||
|
||||
TimerActionRepeat::repeat(move || {
|
||||
periodically_open_connections(
|
||||
config.clone(),
|
||||
tls_config.clone(),
|
||||
load_test_state.clone(),
|
||||
num_active_connections.clone(),
|
||||
)
|
||||
});
|
||||
let interval = config.connection_creation_interval_ms;
|
||||
|
||||
if interval == 0 {
|
||||
loop {
|
||||
if *num_active_connections.borrow() < config.num_connections {
|
||||
if let Err(err) = Connection::run(
|
||||
config.clone(),
|
||||
tls_config.clone(),
|
||||
load_test_state.clone(),
|
||||
num_active_connections.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
::log::error!("connection creation error: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let interval = Duration::from_millis(interval);
|
||||
|
||||
TimerActionRepeat::repeat(move || {
|
||||
periodically_open_connections(
|
||||
config.clone(),
|
||||
interval,
|
||||
tls_config.clone(),
|
||||
load_test_state.clone(),
|
||||
num_active_connections.clone(),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
futures_lite::future::pending::<bool>().await;
|
||||
|
||||
|
|
@ -40,6 +62,7 @@ pub async fn run_socket_thread(
|
|||
|
||||
async fn periodically_open_connections(
|
||||
config: Rc<Config>,
|
||||
interval: Duration,
|
||||
tls_config: Arc<rustls::ClientConfig>,
|
||||
load_test_state: LoadTestState,
|
||||
num_active_connections: Rc<RefCell<usize>>,
|
||||
|
|
@ -49,13 +72,13 @@ async fn periodically_open_connections(
|
|||
if let Err(err) =
|
||||
Connection::run(config, tls_config, load_test_state, num_active_connections).await
|
||||
{
|
||||
eprintln!("connection creation error: {:?}", err);
|
||||
::log::error!("connection creation error: {:?}", err);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
Some(Duration::from_secs(1))
|
||||
Some(interval)
|
||||
}
|
||||
|
||||
struct Connection {
|
||||
|
|
@ -97,10 +120,8 @@ impl Connection {
|
|||
|
||||
*num_active_connections.borrow_mut() += 1;
|
||||
|
||||
println!("run connection");
|
||||
|
||||
if let Err(err) = connection.run_connection_loop().await {
|
||||
eprintln!("connection error: {:?}", err);
|
||||
::log::info!("connection error: {:?}", err);
|
||||
}
|
||||
|
||||
*num_active_connections.borrow_mut() -= 1;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ name = "aquatic_udp"
|
|||
[features]
|
||||
default = ["with-mio"]
|
||||
cpu-pinning = ["aquatic_common/cpu-pinning"]
|
||||
with-glommio = ["glommio", "futures-lite"]
|
||||
with-glommio = ["cpu-pinning", "glommio", "futures-lite"]
|
||||
with-mio = ["crossbeam-channel", "histogram", "mio", "socket2"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
let num_bound_sockets = num_bound_sockets.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("socket");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
config.socket_workers,
|
||||
|
|
@ -93,7 +95,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let request_mesh_builder = request_mesh_builder.clone();
|
||||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("request");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
config.socket_workers,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ path = "src/bin/main.rs"
|
|||
[features]
|
||||
default = ["with-mio"]
|
||||
cpu-pinning = ["aquatic_common/cpu-pinning"]
|
||||
with-glommio = ["async-tungstenite", "futures-lite", "futures", "futures-rustls", "glommio", "rustls-pemfile"]
|
||||
with-glommio = ["cpu-pinning", "async-tungstenite", "futures-lite", "futures", "futures-rustls", "glommio", "rustls-pemfile"]
|
||||
with-mio = ["crossbeam-channel", "histogram", "mio", "native-tls", "parking_lot", "socket2"]
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
let num_bound_sockets = num_bound_sockets.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("socket");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
|
|
@ -67,7 +69,9 @@ pub fn run_inner(config: Config, state: State) -> anyhow::Result<()> {
|
|||
let request_mesh_builder = request_mesh_builder.clone();
|
||||
let response_mesh_builder = response_mesh_builder.clone();
|
||||
|
||||
let executor = LocalExecutorBuilder::default().spawn(move || async move {
|
||||
let builder = LocalExecutorBuilder::default().name("request");
|
||||
|
||||
let executor = builder.spawn(move || async move {
|
||||
#[cfg(feature = "cpu-pinning")]
|
||||
pin_current_if_configured_to(
|
||||
&config.cpu_pinning,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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::access_list::update_access_list;
|
||||
use cfg_if::cfg_if;
|
||||
use signal_hook::{consts::SIGUSR1, iterator::Signals};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue