use std::sync::mpsc;
use std::thread;
use crate::repo::Repo;
pub fn default_parallelism() -> usize {
num_cpus::get()
}
pub fn run_parallel<T, F>(
repos: Vec<Repo>,
max_threads: usize,
f: F,
) -> Vec<(String, T)>
where
T: Send + 'static,
F: Fn(&Repo) -> T + Send + Sync + Clone + 'static,
{
let n_repos = repos.len();
if n_repos == 0 {
return vec![];
}
let (result_tx, result_rx) = mpsc::channel();
let (permit_tx, permit_rx) = mpsc::sync_channel::<()>(max_threads);
for _ in 0..max_threads {
permit_tx.send(()).unwrap();
}
for repo in repos {
permit_rx.recv().unwrap();
let result_tx = result_tx.clone();
let permit_tx = permit_tx.clone();
let f = f.clone();
thread::spawn(move || {
let path = repo.path();
let result = f(&repo);
result_tx.send((path, result)).unwrap();
let _ = permit_tx.send(());
});
}
let mut results = Vec::with_capacity(n_repos);
for _ in 0..n_repos {
results.push(result_rx.recv().unwrap());
}
results
}