rust 42 lines · 7 steps

Aggregating metrics across threads in Rust

Worker threads tally HTTP statuses into one shared, mutex-guarded struct, then the main thread reclaims it.

Explained by highlit
1use std::collections::HashMap;
2use std::sync::{Arc, Mutex};
3use std::thread;
4 
5#[derive(Default)]
6struct Metrics {
7 requests: u64,
8 errors: u64,
9 status_counts: HashMap<u16, u64>,
10}
11 
12fn aggregate_responses(statuses: Vec<u16>, workers: usize) -> Metrics {
13 let metrics = Arc::new(Mutex::new(Metrics::default()));
14 let chunk_size = (statuses.len() + workers - 1) / workers;
15 
16 let mut handles = Vec::with_capacity(workers);
17 for chunk in statuses.chunks(chunk_size) {
18 let metrics = Arc::clone(&metrics);
19 let chunk = chunk.to_vec();
20 
21 handles.push(thread::spawn(move || {
22 for status in chunk {
23 let mut m = metrics.lock().unwrap();
24 m.requests += 1;
25 if status >= 400 {
26 m.errors += 1;
27 }
28 *m.status_counts.entry(status).or_insert(0) += 1;
29 }
30 }));
31 }
32 
33 for handle in handles {
34 handle.join().unwrap();
35 }
36 
37 Arc::try_unwrap(metrics)
38 .ok()
39 .expect("all worker threads have finished")
40 .into_inner()
41 .unwrap()
42}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Arc plus Mutex is the standard pattern for safely sharing mutable state across threads.
  2. 2Splitting work into chunks lets you parallelize a flat list across a fixed number of workers.
  3. 3Once all threads join, Arc::try_unwrap recovers sole ownership so you can unwrap the inner value.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Aggregating metrics across threads in Rust — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code