Skip to content

Commit

Permalink
Fix race condition when trying to fetch the same project from the reg…
Browse files Browse the repository at this point in the history
…istry more than once (#131)

* Implement `Ord` for `ProjectHash`

* Avoid trying to fetch the same project in parallel with a map of mutexes
  • Loading branch information
kylewlacy authored Sep 27, 2024
1 parent f452ea1 commit fce1529
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions crates/brioche-core/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,17 @@ async fn fetch_project_from_registry(
brioche: &Brioche,
project_hash: ProjectHash,
) -> anyhow::Result<PathBuf> {
// Use a mutex to ensure we don't try to fetch the same project more
// than once at a time
static FETCH_PROJECTS_MUTEX: tokio::sync::Mutex<
BTreeMap<ProjectHash, Arc<tokio::sync::Mutex<()>>>,
> = tokio::sync::Mutex::const_new(BTreeMap::new());
let project_mutex = {
let mut fetch_projects = FETCH_PROJECTS_MUTEX.lock().await;
fetch_projects.entry(project_hash).or_default().clone()
};
let _guard = project_mutex.lock().await;

let local_path = brioche.home.join("projects").join(project_hash.to_string());

if tokio::fs::try_exists(&local_path).await? {
Expand Down Expand Up @@ -1665,6 +1676,18 @@ impl std::str::FromStr for ProjectHash {
}
}

impl std::cmp::Ord for ProjectHash {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.as_bytes().cmp(other.0.as_bytes())
}
}

impl std::cmp::PartialOrd for ProjectHash {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

#[derive(Debug, Clone)]
pub struct Workspace {
pub definition: WorkspaceDefinition,
Expand Down

0 comments on commit fce1529

Please sign in to comment.