Hello everyone.
I'm a Rust beginner and I'm trying to rewrite a load testing tool I wrote for work in Rust.
I finally got the code to compile and ran cargo clippy on it, but it feels forced and wrong. What bothers me most is the fact that I'm using self.clone() on every iteration.
I would be grateful for any kind of feedback and a push in the right direction.
#[derive(Clone)]
pub struct Target {
pub url: String,
pub method: String,
pub headers: header::HeaderMap,
pub body: String,
pub cert: Option<PathBuf>,
pub key: Option<PathBuf>,
pub root_ca: Option<PathBuf>,
pub timeout: Duration,
}
impl Target {
pub async fn stress(
&self,
n_requests: usize,
time: Duration,
) -> (Arc<AtomicUsize>, Arc<AtomicUsize>) {
let start = Instant::now();
let client = Arc::new(self.create_client());
let r_count: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0));
let e_count: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0));
while start.elapsed() < time {
let mut tasks = Vec::new();
for _ in 0..n_requests {
let client_clone = client.clone();
let counter = r_count.clone();
let errors = e_count.clone();
let self_clone = self.clone();
tasks.push(tokio::spawn(async move {
let res = client_clone
.request(
Method::from_bytes(self_clone.method.as_bytes()).unwrap(),
self_clone.url.as_str(),
)
.body(self_clone.body)
.send()
.await;
match res {
Ok(_) => counter.fetch_add(1, Ordering::SeqCst),
Err(_) => errors.fetch_add(1, Ordering::SeqCst),
}
}));
}
join_all(tasks).await;
sleep(Duration::from_secs(1));
}
(r_count, e_count)
}
}