Skip to content

Commit 7e82c7a

Browse files
authored
Thread throttle configuration through project (#576)
* Thread throttle configuration through project This commit builds on #573, #574, #575 and threads the configuration of the throttle through all of our generators. This commit finishes up our work introducing new throttles into the project. Signed-off-by: Brian L. Troutwine <brian.troutwine@datadoghq.com> * -rc2 Signed-off-by: Brian L. Troutwine <brian.troutwine@datadoghq.com> --------- Signed-off-by: Brian L. Troutwine <brian.troutwine@datadoghq.com>
1 parent b98292d commit 7e82c7a

12 files changed

Lines changed: 84 additions & 46 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.15.1-rc2]
10+
### Added
11+
- Add 'stable' throttle
12+
- Add 'all-out' throttle
13+
- Allow users to configure generators to use the various throttles
14+
915
## [0.15.1-rc1]
1016
### Added
1117
- Added the ability for users to configure DogStatsD payload kind ratios

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ mod tests {
7373

7474
use http::HeaderMap;
7575

76+
use crate::throttle;
77+
7678
use super::*;
7779

7880
#[test]
@@ -115,6 +117,7 @@ blackhole:
115117
.unwrap(),
116118
block_sizes: Option::default(),
117119
parallel_connections: 5,
120+
throttle: throttle::Config::default(),
118121
})],
119122
blackhole: Some(vec![
120123
blackhole::Config::Tcp(blackhole::tcp::Config {

src/generator/file_gen.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
block::{self, chunk_bytes, construct_block_cache, Block},
3131
payload,
3232
signals::Shutdown,
33-
throttle::Throttle,
33+
throttle::{self, Throttle},
3434
};
3535

3636
#[derive(thiserror::Error, Debug)]
@@ -86,6 +86,9 @@ pub struct Config {
8686
/// tailing software to remove old files.
8787
#[serde(default = "default_rotation")]
8888
rotate: bool,
89+
/// The load throttle configuration
90+
#[serde(default)]
91+
pub throttle: throttle::Config,
8992
}
9093

9194
#[derive(Debug)]
@@ -154,7 +157,7 @@ impl FileGen {
154157
let mut handles = Vec::new();
155158
let file_index = Arc::new(AtomicU32::new(0));
156159
for _ in 0..config.duplicates {
157-
let throttle = Throttle::new(bytes_per_second);
160+
let throttle = Throttle::new_with_config(config.throttle, bytes_per_second);
158161

159162
let block_cache =
160163
construct_block_cache(&mut rng, &config.variant, &block_chunks, &labels);

src/generator/file_tree.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ use serde::Deserialize;
2222
use tokio::{fs::create_dir, fs::rename, fs::File};
2323
use tracing::info;
2424

25-
use crate::{signals::Shutdown, throttle::Throttle};
25+
use crate::{
26+
signals::Shutdown,
27+
throttle::{self, Throttle},
28+
};
2629

2730
static FILE_EXTENSION: &str = "txt";
2831

@@ -68,7 +71,7 @@ fn default_rename_per_name() -> NonZeroU32 {
6871
NonZeroU32::new(1).unwrap()
6972
}
7073

71-
#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
74+
#[derive(Debug, Deserialize, PartialEq, Clone)]
7275
/// Configuration of [`FileTree`]
7376
pub struct Config {
7477
/// The seed for random operations against this target
@@ -96,6 +99,9 @@ pub struct Config {
9699
#[serde(default = "default_rename_per_name")]
97100
/// The number of rename per second
98101
pub rename_per_second: NonZeroU32,
102+
/// The load throttle configuration
103+
#[serde(default)]
104+
pub throttle: throttle::Config,
99105
}
100106

101107
#[derive(Debug)]
@@ -105,8 +111,8 @@ pub struct Config {
105111
/// this without coordination to the target.
106112
pub struct FileTree {
107113
name_len: NonZeroUsize,
108-
open_per_second: NonZeroU32,
109-
rename_per_second: NonZeroU32,
114+
open_throttle: Throttle,
115+
rename_throttle: Throttle,
110116
total_folder: usize,
111117
nodes: VecDeque<PathBuf>,
112118
rng: StdRng,
@@ -124,10 +130,12 @@ impl FileTree {
124130
let mut rng = StdRng::from_seed(config.seed);
125131
let (nodes, _total_files, total_folder) = generate_tree(&mut rng, config);
126132

133+
let open_throttle = Throttle::new_with_config(config.throttle, config.open_per_second);
134+
let rename_throttle = Throttle::new_with_config(config.throttle, config.rename_per_second);
127135
Ok(Self {
128136
name_len: config.name_len,
129-
open_per_second: config.open_per_second,
130-
rename_per_second: config.rename_per_second,
137+
open_throttle,
138+
rename_throttle,
131139
total_folder,
132140
nodes,
133141
rng,
@@ -149,15 +157,12 @@ impl FileTree {
149157
///
150158
/// Function will panic if one node is not path is not populated properly
151159
pub async fn spin(mut self) -> Result<(), Error> {
152-
let mut open_throttle = Throttle::new(self.open_per_second);
153-
let mut rename_throttle = Throttle::new(self.rename_per_second);
154-
155160
let mut iter = self.nodes.iter().cycle();
156161
let mut folders = Vec::with_capacity(self.total_folder);
157162

158163
loop {
159164
tokio::select! {
160-
_ = open_throttle.wait() => {
165+
_ = self.open_throttle.wait() => {
161166
let node = iter.next().unwrap();
162167
if node.exists() {
163168
File::open(node.as_path()).await?;
@@ -169,7 +174,7 @@ impl FileTree {
169174
}
170175
}
171176
},
172-
_ = rename_throttle.wait() => {
177+
_ = self.rename_throttle.wait() => {
173178
if let Some(folder) = folders.choose_mut(&mut self.rng) {
174179
rename_folder(&mut self.rng, folder, self.name_len.get()).await?;
175180
}

src/generator/grpc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
block::{self, chunk_bytes, construct_block_cache, Block},
2323
payload,
2424
signals::Shutdown,
25-
throttle::Throttle,
25+
throttle::{self, Throttle},
2626
};
2727

2828
/// Errors produced by [`Grpc`]
@@ -57,6 +57,9 @@ pub struct Config {
5757
pub maximum_prebuild_cache_size_bytes: byte_unit::Byte,
5858
/// The total number of parallel connections to maintain
5959
pub parallel_connections: u16,
60+
/// The load throttle configuration
61+
#[serde(default)]
62+
pub throttle: throttle::Config,
6063
}
6164

6265
/// No-op tonic codec. Sends raw bytes and returns the number of bytes received.
@@ -182,13 +185,14 @@ impl Grpc {
182185
.cloned()
183186
.expect("target_uri should have an RPC path");
184187

188+
let throttle = Throttle::new_with_config(config.throttle, bytes_per_second);
185189
Ok(Self {
186190
target_uri,
187191
rpc_path,
188192
config,
189193
shutdown,
190194
block_cache,
191-
throttle: Throttle::new(bytes_per_second),
195+
throttle,
192196
metric_labels: labels,
193197
})
194198
}

src/generator/http.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
block::{self, chunk_bytes, construct_block_cache, Block},
2020
payload,
2121
signals::Shutdown,
22-
throttle::Throttle,
22+
throttle::{self, Throttle},
2323
};
2424

2525
static CONNECTION_SEMAPHORE: OnceCell<Semaphore> = OnceCell::new();
@@ -56,6 +56,9 @@ pub struct Config {
5656
pub block_sizes: Option<Vec<byte_unit::Byte>>,
5757
/// The total number of parallel connections to maintain
5858
pub parallel_connections: u16,
59+
/// The load throttle configuration
60+
#[serde(default)]
61+
pub throttle: throttle::Config,
5962
}
6063

6164
#[derive(thiserror::Error, Debug)]
@@ -155,7 +158,7 @@ impl Http {
155158
method: hyper::Method::POST,
156159
headers: config.headers,
157160
block_cache,
158-
throttle: Throttle::new(bytes_per_second),
161+
throttle: Throttle::new_with_config(config.throttle, bytes_per_second),
159162
metric_labels: labels,
160163
shutdown,
161164
})

src/generator/process_tree.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
//! losely to the target but instead, without coordination, merely generates
55
//! a process tree.
66
7-
use crate::{signals::Shutdown, throttle::Throttle};
7+
use crate::{
8+
signals::Shutdown,
9+
throttle::{self, Throttle},
10+
};
811
use is_executable::IsExecutable;
912
use nix::{
1013
sys::wait::{waitpid, WaitPidFlag, WaitStatus},
@@ -107,7 +110,7 @@ fn default_envs_count() -> NonZeroU32 {
107110
NonZeroU32::new(10).unwrap()
108111
}
109112

110-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
113+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
111114
/// Configuration of [`ProcessTree`]
112115
#[serde(tag = "mode", rename_all = "snake_case")]
113116
pub enum Args {
@@ -117,14 +120,14 @@ pub enum Args {
117120
Generate(GenerateArgs),
118121
}
119122

120-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
123+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
121124
/// Configuration of [`ProcessTree`]
122125
pub struct StaticArgs {
123126
/// Argumments used with the `static` mode
124127
pub values: Vec<String>,
125128
}
126129

127-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
130+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
128131
/// Configuration of [`ProcessTree`]
129132
pub struct GenerateArgs {
130133
/// The maximum number argument per Process. Used by the `generate` mode
@@ -135,7 +138,7 @@ pub struct GenerateArgs {
135138
pub count: NonZeroU32,
136139
}
137140

138-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
141+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
139142
/// Configuration of [`ProcessTree`]
140143
#[serde(tag = "mode", rename_all = "snake_case")]
141144
pub enum Envs {
@@ -145,14 +148,14 @@ pub enum Envs {
145148
Generate(GenerateEnvs),
146149
}
147150

148-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
151+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
149152
/// Configuration of [`ProcessTree`]
150153
pub struct StaticEnvs {
151154
/// Environment variables used with the `static` mode
152155
pub values: Vec<String>,
153156
}
154157

155-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
158+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
156159
/// Configuration of [`ProcessTree`]
157160
pub struct GenerateEnvs {
158161
/// The maximum number environment variable per Process. Used by the `generate` mode
@@ -179,7 +182,7 @@ impl StaticEnvs {
179182
}
180183
}
181184

182-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
185+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
183186
/// Configuration of [`ProcessTree`]
184187
pub struct Executable {
185188
/// Path of the executable
@@ -190,7 +193,7 @@ pub struct Executable {
190193
pub envs: Envs,
191194
}
192195

193-
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
196+
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
194197
/// Configuration of [`ProcessTree`]
195198
pub struct Config {
196199
/// The seed for random operations against this target
@@ -209,6 +212,9 @@ pub struct Config {
209212
pub process_sleep_ns: NonZeroU32,
210213
/// List of executables
211214
pub executables: Vec<Executable>,
215+
/// The load throttle configuration
216+
#[serde(default)]
217+
pub throttle: throttle::Config,
212218
}
213219

214220
impl Config {
@@ -239,7 +245,7 @@ impl Config {
239245
pub struct ProcessTree {
240246
lading_path: PathBuf,
241247
config_content: String,
242-
max_tree_per_second: NonZeroU32,
248+
throttle: Throttle,
243249
shutdown: Shutdown,
244250
}
245251

@@ -256,11 +262,12 @@ impl ProcessTree {
256262
Err(e) => return Err(Error::from(e)),
257263
};
258264

265+
let throttle = Throttle::new_with_config(config.throttle, config.max_tree_per_second);
259266
match serde_yaml::to_string(config) {
260267
Ok(serialized) => Ok(Self {
261268
lading_path,
262269
config_content: serialized,
263-
max_tree_per_second: config.max_tree_per_second,
270+
throttle,
264271
shutdown,
265272
}),
266273
Err(e) => Err(Error::from(e)),
@@ -280,12 +287,11 @@ impl ProcessTree {
280287
/// Panic if the lading path can't determine.
281288
///
282289
pub async fn spin(mut self) -> Result<(), Error> {
283-
let mut process_throttle = Throttle::new(self.max_tree_per_second);
284290
let lading_path = self.lading_path.to_str().unwrap();
285291

286292
loop {
287293
tokio::select! {
288-
_ = process_throttle.wait() => {
294+
_ = self.throttle.wait() => {
289295
// using pid as target pid just to pass laging clap constraints
290296
let output = Command::new(lading_path)
291297
.args(["--target-pid", "1"])

src/generator/splunk_hec.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
payload,
3131
payload::SplunkHecEncoding,
3232
signals::Shutdown,
33-
throttle::Throttle,
33+
throttle::{self, Throttle},
3434
};
3535

3636
static CONNECTION_SEMAPHORE: OnceCell<Semaphore> = OnceCell::new();
@@ -40,7 +40,7 @@ const SPLUNK_HEC_TEXT_PATH: &str = "/services/collector/raw";
4040
const SPLUNK_HEC_CHANNEL_HEADER: &str = "x-splunk-request-channel";
4141

4242
/// Optional Splunk HEC indexer acknowledgements configuration
43-
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
43+
#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
4444
pub struct AckSettings {
4545
/// The time in seconds between queries to /services/collector/ack
4646
pub ack_query_interval_seconds: u64,
@@ -50,7 +50,7 @@ pub struct AckSettings {
5050
}
5151

5252
/// Configuration for [`SplunkHec`]
53-
#[derive(Deserialize, Debug, PartialEq, Eq)]
53+
#[derive(Deserialize, Debug, PartialEq)]
5454
pub struct Config {
5555
/// The seed for random operations against this target
5656
pub seed: [u8; 32],
@@ -71,6 +71,9 @@ pub struct Config {
7171
pub block_sizes: Option<Vec<byte_unit::Byte>>,
7272
/// The total number of parallel connections to maintain
7373
pub parallel_connections: u16,
74+
/// The load throttle configuration
75+
#[serde(default)]
76+
pub throttle: throttle::Config,
7477
}
7578

7679
#[derive(thiserror::Error, Debug, Clone, Copy)]
@@ -192,7 +195,7 @@ impl SplunkHec {
192195
uri,
193196
token: config.token,
194197
block_cache,
195-
throttle: Throttle::new(bytes_per_second),
198+
throttle: Throttle::new_with_config(config.throttle, bytes_per_second),
196199
metric_labels: labels,
197200
shutdown,
198201
})

0 commit comments

Comments
 (0)