Skip to content

Commit

Permalink
Run solutions in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
mo8it committed Jun 10, 2024
1 parent 98db579 commit 42a3503
Showing 1 changed file with 49 additions and 25 deletions.
74 changes: 49 additions & 25 deletions src/dev/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ use std::{
fs::{self, read_dir, OpenOptions},
io::{self, Read, Write},
path::{Path, PathBuf},
sync::{
atomic::{self, AtomicBool},
Mutex,
},
thread,
};

use crate::{
Expand Down Expand Up @@ -167,36 +172,52 @@ fn check_exercises(info_file: &InfoFile) -> Result<()> {
}

fn check_solutions(require_solutions: bool, info_file: &InfoFile) -> Result<()> {
let mut paths = hashbrown::HashSet::with_capacity(info_file.exercises.len());
let target_dir = parse_target_dir()?;
let mut output = Vec::with_capacity(OUTPUT_CAPACITY);

for exercise_info in &info_file.exercises {
let path = exercise_info.sol_path();
if !Path::new(&path).exists() {
if require_solutions {
bail!("Exercise {} is missing a solution", exercise_info.name);
}

// No solution to check.
continue;
let paths = Mutex::new(hashbrown::HashSet::with_capacity(info_file.exercises.len()));
let error_occured = AtomicBool::new(false);

println!("Running all solutions. This may take a while...\n");
thread::scope(|s| {
for exercise_info in &info_file.exercises {
s.spawn(|| {
let error = |e| {
let mut stderr = io::stderr().lock();
stderr.write_all(e).unwrap();
stderr
.write_all(b"\nFailed to run the solution of the exercise ")
.unwrap();
stderr.write_all(exercise_info.name.as_bytes()).unwrap();
stderr.write_all(SEPARATOR).unwrap();
error_occured.store(true, atomic::Ordering::Relaxed);
};

let path = exercise_info.sol_path();
if !Path::new(&path).exists() {
if require_solutions {
error(b"Solution missing");
}

// No solution to check.
return;
}

let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
match exercise_info.run_solution(&mut output, &target_dir) {
Ok(true) => {
paths.lock().unwrap().insert(PathBuf::from(path));
}
Ok(false) => error(&output),
Err(e) => error(e.to_string().as_bytes()),
}
});
}
});

println!("Running the solution of {}", exercise_info.name);
let success = exercise_info.run_solution(&mut output, &target_dir)?;
if !success {
io::stderr().write_all(&output)?;

bail!(
"Failed to run the solution of the exercise {}",
exercise_info.name,
);
}

paths.insert(PathBuf::from(path));
if error_occured.load(atomic::Ordering::Relaxed) {
bail!("At least one solution failed. See the output above.");
}

check_unexpected_files("solutions", &paths)?;
check_unexpected_files("solutions", &paths.into_inner().unwrap())?;

Ok(())
}
Expand Down Expand Up @@ -224,3 +245,6 @@ pub fn check(require_solutions: bool) -> Result<()> {

Ok(())
}

const SEPARATOR: &[u8] =
b"\n========================================================================================\n";

0 comments on commit 42a3503

Please sign in to comment.