fix: prevent concurrent operations on plugin global settings files to ensure did_receive_global_settings can read a complete file

This commit is contained in:
nekename committed 2026-02-19 18:07:12 +00:00
1 parent 612dc3a3b0
commit ea0619db71
2 files changed
+19 -4

No files matched your search

+6 -2
View File
@@ -2,6 +2,7 @@ use crate::events::outbound::settings as outbound;
use crate::shared::ActionContext;
use crate::store::profiles::{acquire_locks, acquire_locks_mut, get_instance, get_instance_mut, save_profile};
use std::io::Write;
use std::str::FromStr;
pub async fn set_settings(event: super::ContextAndPayloadEvent<serde_json::Value>, from_property_inspector: bool) -> Result<(), anyhow::Error> {
@@ -41,8 +42,11 @@ pub async fn set_global_settings(event: super::ContextAndPayloadEvent<serde_json
let settings_dir = crate::shared::config_dir().join("settings");
tokio::fs::create_dir_all(&settings_dir).await?;
let path = settings_dir.join(uuid.clone() + ".json");
tokio::fs::write(path, event.payload.to_string()).await?;
let mut file = std::fs::OpenOptions::new().write(true).truncate(true).create(true).open(settings_dir.join(uuid.clone() + ".json"))?;
file.lock()?;
file.write_all(event.payload.to_string().as_bytes())?;
file.sync_data()?;
file.unlock()?;
}
outbound::did_receive_global_settings(&uuid, !from_property_inspector).await?;
+13 -2
View File
@@ -2,6 +2,8 @@ use super::{GenericInstancePayload, send_to_plugin, send_to_property_inspector};
use crate::shared::ActionContext;
use std::io::Read;
use serde::Serialize;
#[derive(Serialize)]
@@ -42,8 +44,17 @@ struct DidReceiveGlobalSettingsEvent {
pub async fn did_receive_global_settings(context: &str, to_property_inspector: bool) -> Result<(), anyhow::Error> {
let settings_dir = crate::shared::config_dir().join("settings");
let path = settings_dir.join(format!("{}.json", context));
let settings: serde_json::Value = match tokio::fs::read(path).await {
Ok(contents) => serde_json::from_slice(&contents)?,
let settings: serde_json::Value = match std::fs::File::open(&path) {
Ok(mut file) => {
file.lock_shared()?;
let buf = &mut Vec::new();
let settings = match file.read_to_end(buf) {
Ok(_) => serde_json::from_slice(buf)?,
Err(_) => serde_json::Value::Object(serde_json::Map::new()),
};
file.unlock()?;
settings
}
Err(_) => serde_json::Value::Object(serde_json::Map::new()),
};