Skip to content
This repository has been archived by the owner on Dec 21, 2024. It is now read-only.

Commit

Permalink
chore(toolchain): add mutex lock on meta file to prevent race conditi…
Browse files Browse the repository at this point in the history
…ons when writing (#404)
  • Loading branch information
NathanFlurry committed Sep 17, 2024
1 parent dc31592 commit c259044
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
14 changes: 11 additions & 3 deletions packages/toolchain/src/config/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ pub struct ProcessState {

lazy_static! {
static ref GLOBAL_META: Mutex<HashMap<PathBuf, Meta>> = Mutex::new(HashMap::new());

/// Lock on writing to the file.
static ref META_FILE_LOCK: Mutex<()> = Mutex::new(());
}

/// Gets the global config instance.
Expand All @@ -97,7 +100,8 @@ where
let path = paths::meta_config_file(base_data_dir)?;

let mut config = match fs::read_to_string(&path).await {
Result::Ok(config) => serde_json::from_str(&config)?,
Result::Ok(config) => serde_json::from_str(&config)
.context(format!("deserialize meta ({})", path.display()))?,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Meta::default(),
Err(err) => return Err(err.into()),
};
Expand All @@ -121,8 +125,12 @@ async fn write(base_data_dir: &PathBuf) -> Result<()> {
serde_json::to_string(meta).map_err(Into::into)
})
.await?;
fs::create_dir_all(paths::user_config_dir(base_data_dir)?).await?;
fs::write(paths::meta_config_file(base_data_dir)?, json_str).await?;

{
let _write_guard = META_FILE_LOCK.lock().await;
fs::create_dir_all(paths::user_config_dir(base_data_dir)?).await?;
fs::write(paths::meta_config_file(base_data_dir)?, json_str).await?;
}

Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions packages/toolchain/src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ where
.add_source(config::File::from(paths::project_settings_config_file()?));
}

let config = config_builder.build().await.context("find config")?;
let config = config_builder.build().await.context("find settings")?;
let mut settings = config
.try_deserialize::<Settings>()
.context("deserialize config")?;
.context("deserialize settings")?;

let result = cb(&mut settings)?;
global_settings.insert(data_dir.clone(), settings);
Expand Down

0 comments on commit c259044

Please sign in to comment.