diff --git a/crates/brioche-core/src/project.rs b/crates/brioche-core/src/project.rs index 331c715..0aa799b 100644 --- a/crates/brioche-core/src/project.rs +++ b/crates/brioche-core/src/project.rs @@ -985,6 +985,17 @@ async fn fetch_project_from_registry( brioche: &Brioche, project_hash: ProjectHash, ) -> anyhow::Result { + // 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>>, + > = 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? { @@ -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 { + Some(self.cmp(other)) + } +} + #[derive(Debug, Clone)] pub struct Workspace { pub definition: WorkspaceDefinition,