Skip to content

Commit

Permalink
re-add tracking of executed tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
syphar committed Mar 5, 2023
1 parent 6439e89 commit d49b0f2
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
44 changes: 22 additions & 22 deletions src/justfile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use parallel::Ran;
use std::sync::Arc;
use {super::*, serde::Serialize};

Expand Down Expand Up @@ -254,14 +255,10 @@ impl<'src> Justfile<'src> {
search,
};

// let mut ran = BTreeSet::new();
let ran = Ran::new();
parallel::task_scope(config.parallel, |scope| {
for (recipe, arguments) in grouped {
scope.run(|| {
Self::run_recipe(
&context, recipe, arguments, &dotenv, search, /*&mut ran*/
)
})?;
scope.run(|| Self::run_recipe(&context, recipe, arguments, &dotenv, search, &ran))?;
}
Ok(())
})?;
Expand All @@ -287,16 +284,16 @@ impl<'src> Justfile<'src> {
arguments: &[&str],
dotenv: &BTreeMap<String, String>,
search: &Search,
// ran: &mut BTreeSet<Vec<String>>,
ran: &Ran,
) -> RunResult<'src, ()> {
let mut invocation = vec![recipe.name().to_owned()];
for argument in arguments {
invocation.push((*argument).to_string());
}

// if ran.contains(&invocation) {
// return Ok(());
// }
if ran.contains(&invocation) {
return Ok(());
}

let (outer, positional) = Evaluator::evaluate_parameters(
context.config,
Expand Down Expand Up @@ -327,7 +324,7 @@ impl<'src> Justfile<'src> {
&arguments.iter().map(String::as_ref).collect::<Vec<&str>>(),
dotenv,
search,
// ran,
ran,
)
})?;
}
Expand All @@ -337,7 +334,7 @@ impl<'src> Justfile<'src> {
recipe.run(context, dotenv, scope.child(), search, &positional)?;

{
// let mut ran = BTreeSet::new();
let ran = Ran::new();

parallel::task_scope(context.config.parallel, |scope| {
for Dependency { recipe, arguments } in recipe.dependencies.iter().skip(recipe.priors) {
Expand All @@ -351,22 +348,25 @@ impl<'src> Justfile<'src> {
);
}

scope.run(move || {
Self::run_recipe(
context,
recipe,
&evaluated.iter().map(String::as_ref).collect::<Vec<&str>>(),
dotenv,
search,
// &mut ran,
)
scope.run({
let ran = ran.clone();
move || {
Self::run_recipe(
context,
recipe,
&evaluated.iter().map(String::as_ref).collect::<Vec<&str>>(),
dotenv,
search,
&ran,
)
}
})?;
}
Ok(())
})?;
}

// ran.insert(invocation);
ran.insert(invocation);
Ok(())
}

Expand Down
44 changes: 44 additions & 0 deletions src/parallel.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::RunResult;
use crossbeam::thread;
use std::collections::HashSet;
use std::sync::{Arc, Mutex};

type ScopeResult<'src> = RunResult<'src, ()>;

Expand All @@ -10,6 +12,7 @@ pub(crate) struct TaskScope<'env, 'src, 'inner_scope> {
}

impl<'env, 'src, 'inner_scope> TaskScope<'env, 'src, 'inner_scope> {
/// run the given task, either directly synchronously or spawned in a background thread.
pub(crate) fn run<'scope, F>(&'scope mut self, f: F) -> ScopeResult<'src>
where
'src: 'env,
Expand All @@ -31,6 +34,9 @@ impl<'env, 'src, 'inner_scope> TaskScope<'env, 'src, 'inner_scope> {
/// run. The first error will be returned as result of this `task_scope`.
///
/// Only works for tasks with an `RunResult<'src, ()>` result type.
///
/// When `parallel` is set to `false`, the tasks are directly executed
/// when calling `run`.
pub(crate) fn task_scope<'env, 'src, F>(parallel: bool, f: F) -> ScopeResult<'src>
where
F: for<'inner_scope> FnOnce(&mut TaskScope<'env, 'src, 'inner_scope>) -> ScopeResult<'src>,
Expand All @@ -51,3 +57,41 @@ where
})
.expect("could not join thread")
}

/// track which tasks were already run, across all running threads.
#[derive(Clone)]
pub(crate) struct Ran(Arc<Mutex<HashSet<Vec<String>>>>);

impl Ran {
pub(crate) fn new() -> Self {
Self(Arc::new(Mutex::new(HashSet::new())))
}

pub(crate) fn insert(&self, args: Vec<String>) {
let mut ran = self.0.lock().unwrap();
ran.insert(args);
}

pub(crate) fn contains(&self, args: &Vec<String>) -> bool {
let ran = self.0.lock().unwrap();
ran.contains(args)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_ran_empty() {
let r = Ran::new();
assert!(!r.contains(&vec![]));
}

#[test]
fn test_ran_insert_contains() {
let r = Ran::new();
r.insert(vec!["1".into(), "2".into(), "3".into()]);
assert!(r.contains(&vec!["1".into(), "2".into(), "3".into()]));
}
}

0 comments on commit d49b0f2

Please sign in to comment.