Skip to content

Commit

Permalink
new: Add caching to VCS layer. (#161)
Browse files Browse the repository at this point in the history
* Add caching.

* Use same instance.

* Update changelog.

* Trigger runs.

* Remove comment.
  • Loading branch information
milesj committed Jun 27, 2022
1 parent 2e79637 commit 215033b
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 18 deletions.
2 changes: 1 addition & 1 deletion crates/cli/src/commands/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn gather_touched_files(
) -> Result<TouchedFilePaths, WorkspaceError> {
print_header("Gathering touched files");

let vcs = workspace.detect_vcs()?;
let vcs = &workspace.vcs;
let default_branch = vcs.get_default_branch();
let current_branch = vcs.get_local_branch().await?;

Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn get_touched_files(
status: &RunStatus,
upstream: bool,
) -> Result<TouchedFilePaths, WorkspaceError> {
let vcs = workspace.detect_vcs()?;
let vcs = &workspace.vcs;

let touched_files = if upstream {
vcs.get_touched_files_between_revisions(vcs.get_default_branch(), "HEAD")
Expand Down
2 changes: 1 addition & 1 deletion crates/workspace/src/actions/hashing/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub async fn create_target_hasher(
task: &Task,
passthrough_args: &[String],
) -> Result<TargetHasher, WorkspaceError> {
let vcs = workspace.detect_vcs()?;
let vcs = &workspace.vcs;
let globset = task.create_globset()?;
let mut hasher = TargetHasher::new(workspace.config.node.version.clone());

Expand Down
32 changes: 27 additions & 5 deletions crates/workspace/src/vcs/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ use ignore::gitignore::{Gitignore, GitignoreBuilder};
use moon_utils::fs;
use moon_utils::process::{output_to_string, output_to_trimmed_string, Command};
use regex::Regex;
use std::collections::{BTreeMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tokio::sync::RwLock;

pub struct Git {
cache: Arc<RwLock<HashMap<String, String>>>,
default_branch: String,
ignore: Option<Gitignore>,
working_dir: PathBuf,
Expand All @@ -30,6 +33,7 @@ impl Git {
}

Ok(Git {
cache: Arc::new(RwLock::new(HashMap::new())),
default_branch: String::from(default_branch),
ignore,
working_dir: working_dir.to_path_buf(),
Expand Down Expand Up @@ -71,13 +75,30 @@ impl Git {
}

async fn run_command(&self, command: &mut Command, trim: bool) -> VcsResult<String> {
let output = command.exec_capture_output().await?;
let (cache_key, _) = command.get_command_line();

// Read first before locking with a write
{
let cache = self.cache.read().await;

if trim {
return Ok(output_to_trimmed_string(&output.stdout));
if cache.contains_key(&cache_key) {
return Ok(cache.get(&cache_key).unwrap().clone());
}
}

Ok(output_to_string(&output.stdout))
// Otherwise lock and calculate a new value to write
let mut cache = self.cache.write().await;
let output = command.exec_capture_output().await?;

let value = if trim {
output_to_trimmed_string(&output.stdout)
} else {
output_to_string(&output.stdout)
};

cache.insert(cache_key.to_owned(), value.clone());

Ok(value)
}
}

Expand Down Expand Up @@ -147,6 +168,7 @@ impl Vcs for Git {
true,
)
.await?;

let mut map = BTreeMap::new();

if output.is_empty() {
Expand Down
31 changes: 26 additions & 5 deletions crates/workspace/src/vcs/svn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ use async_trait::async_trait;
use moon_utils::fs;
use moon_utils::process::{output_to_string, output_to_trimmed_string, Command};
use regex::Regex;
use std::collections::{BTreeMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::fs::metadata;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::SystemTime;
use tokio::sync::RwLock;

// TODO: This code hasn't been tested yet and may not be accurate!

pub struct Svn {
cache: Arc<RwLock<HashMap<String, String>>>,
default_branch: String,
working_dir: PathBuf,
}

impl Svn {
pub fn new(default_branch: &str, working_dir: &Path) -> Self {
Svn {
cache: Arc::new(RwLock::new(HashMap::new())),
default_branch: String::from(default_branch),
working_dir: working_dir.to_path_buf(),
}
Expand Down Expand Up @@ -103,13 +107,30 @@ impl Svn {
}

async fn run_command(&self, command: &mut Command, trim: bool) -> VcsResult<String> {
let output = command.exec_capture_output().await?;
let (cache_key, _) = command.get_command_line();

// Read first before locking with a write
{
let cache = self.cache.read().await;

if trim {
return Ok(output_to_trimmed_string(&output.stdout));
if cache.contains_key(&cache_key) {
return Ok(cache.get(&cache_key).unwrap().clone());
}
}

Ok(output_to_string(&output.stdout))
// Otherwise lock and calculate a new value to write
let mut cache = self.cache.write().await;
let output = command.exec_capture_output().await?;

let value = if trim {
output_to_trimmed_string(&output.stdout)
} else {
output_to_string(&output.stdout)
};

cache.insert(cache_key.to_owned(), value.clone());

Ok(value)
}
}

Expand Down
10 changes: 5 additions & 5 deletions crates/workspace/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ pub struct Workspace {
/// The root `tsconfig.json`.
pub tsconfig_json: Option<TsConfigJson>,

/// Configured version control system.
pub vcs: Box<dyn Vcs + Send + Sync>,

/// The current working directory.
pub working_dir: PathBuf,
}
Expand Down Expand Up @@ -178,6 +181,7 @@ impl Workspace {
let toolchain = Toolchain::create(&root_dir, &config).await?;
let projects =
ProjectGraph::create(&root_dir, project_config, &config.projects, &cache).await?;
let vcs = VcsManager::load(&config, &root_dir)?;

Ok(Workspace {
cache,
Expand All @@ -187,12 +191,8 @@ impl Workspace {
root: root_dir,
toolchain,
tsconfig_json,
vcs,
working_dir,
})
}

/// Detect the version control system currently being used.
pub fn detect_vcs(&self) -> Result<Box<dyn Vcs + Send + Sync>, WorkspaceError> {
VcsManager::load(&self.config, &self.working_dir)
}
}
7 changes: 7 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

#### 🚀 Updates

- Added caching to our VCS layer which should greatly reduce the amount of `git` commands being
executed.

### 0.4.1

#### 🐞 Fixes
Expand Down

0 comments on commit 215033b

Please sign in to comment.