Run the final check in parallel

This commit is contained in:
mo8it 2024-07-28 17:39:46 +02:00
parent 2ae9f3555b
commit 3a99542f73
2 changed files with 43 additions and 21 deletions

View file

@ -1,3 +1,10 @@
<a name="6.1.1"></a>
## 6.1.1 (UNRELEASED)
- Run the final check of all exercises in parallel.
- Small exercise improvements.
<a name="6.1.0"></a> <a name="6.1.0"></a>
## 6.1.0 (2024-07-10) ## 6.1.0 (2024-07-10)

View file

@ -1,11 +1,11 @@
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Error, Result};
use ratatui::crossterm::style::Stylize;
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
fs::{self, File}, fs::{self, File},
io::{Read, StdoutLock, Write}, io::{Read, StdoutLock, Write},
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{Command, Stdio}, process::{Command, Stdio},
thread,
}; };
use crate::{ use crate::{
@ -373,34 +373,50 @@ impl AppState {
if let Some(ind) = self.next_pending_exercise_ind() { if let Some(ind) = self.next_pending_exercise_ind() {
self.set_current_exercise_ind(ind)?; self.set_current_exercise_ind(ind)?;
return Ok(ExercisesProgress::NewPending); return Ok(ExercisesProgress::NewPending);
} }
writer.write_all(RERUNNING_ALL_EXERCISES_MSG)?; writer.write_all(RERUNNING_ALL_EXERCISES_MSG)?;
let n_exercises = self.exercises.len();
let pending_exercise_ind = thread::scope(|s| {
let handles = self
.exercises
.iter_mut()
.map(|exercise| {
s.spawn(|| {
let mut output = Vec::with_capacity(OUTPUT_CAPACITY); let mut output = Vec::with_capacity(OUTPUT_CAPACITY);
for (exercise_ind, exercise) in self.exercises().iter().enumerate() { let success = exercise.run_exercise(&mut output, &self.target_dir)?;
write!(writer, "Running {exercise} ... ")?; exercise.done = success;
Ok::<_, Error>(success)
})
})
.collect::<Vec<_>>();
for (exercise_ind, handle) in handles.into_iter().enumerate() {
write!(writer, "\rProgress: {exercise_ind}/{n_exercises}")?;
writer.flush()?; writer.flush()?;
let success = exercise.run_exercise(&mut output, &self.target_dir)?; let success = handle.join().unwrap()?;
if !success { if !success {
writeln!(writer, "{}\n", "FAILED".red())?; writer.write_all(b"\n\n")?;
return Ok(Some(exercise_ind));
self.current_exercise_ind = exercise_ind; }
// No check if the exercise is done before setting it to pending
// because no pending exercise was found.
self.exercises[exercise_ind].done = false;
self.n_done -= 1;
self.write()?;
return Ok(ExercisesProgress::NewPending);
} }
writeln!(writer, "{}", "ok".green())?; Ok::<_, Error>(None)
})?;
if let Some(pending_exercise_ind) = pending_exercise_ind {
self.current_exercise_ind = pending_exercise_ind;
self.n_done = self
.exercises
.iter()
.filter(|exercise| exercise.done)
.count() as u16;
self.write()?;
return Ok(ExercisesProgress::NewPending);
} }
// Write that the last exercise is done. // Write that the last exercise is done.
@ -426,7 +442,6 @@ Try running `cargo --version` to diagnose the problem.";
const RERUNNING_ALL_EXERCISES_MSG: &[u8] = b" const RERUNNING_ALL_EXERCISES_MSG: &[u8] = b"
All exercises seem to be done. All exercises seem to be done.
Recompiling and running all exercises to make sure that all of them are actually done. Recompiling and running all exercises to make sure that all of them are actually done.
"; ";
const FENISH_LINE: &str = "+----------------------------------------------------+ const FENISH_LINE: &str = "+----------------------------------------------------+