From 2e97bffc822fcb3d5608334bd21f80e5547356d7 Mon Sep 17 00:00:00 2001 From: alemi Date: Tue, 2 Jan 2024 02:43:38 +0100 Subject: [PATCH] fix: make file storage threadsafe --- src/storage.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/storage.rs b/src/storage.rs index 674b0fd..4a52f7d 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,3 +1,5 @@ +use tokio::sync::RwLock; + use crate::model::Page; @@ -19,12 +21,12 @@ pub trait StorageStrategy : Send + Sync { /// this strategy is rather inefficient since it has to iterate the whole file every time, but it /// requires literally zero effort pub struct JsonFileStorageStrategy { - path: String, + path: RwLock, // only needed to prevent race conditions on insertion } impl JsonFileStorageStrategy { pub fn new(path: &str) -> Self { - JsonFileStorageStrategy { path: path.to_string() } + JsonFileStorageStrategy { path: RwLock::new(path.to_string()) } } } @@ -32,16 +34,18 @@ impl JsonFileStorageStrategy { #[async_trait::async_trait] impl StorageStrategy for JsonFileStorageStrategy { async fn archive(&mut self, payload: Page) -> Result<(), StorageStrategyError> { - let file_content = std::fs::read_to_string(&self.path)?; + let path = self.path.write().await; + let file_content = std::fs::read_to_string(*path)?; let mut current_content : Vec = serde_json::from_str(&file_content)?; current_content.push(payload); let updated_content = serde_json::to_string(¤t_content)?; - std::fs::write(&self.path, updated_content)?; + std::fs::write(*path, updated_content)?; Ok(()) } async fn extract(&self, offset: usize, window: usize) -> Result, StorageStrategyError> { - let file_content = std::fs::read_to_string(&self.path)?; + let path = self.path.read().await; + let file_content = std::fs::read_to_string(*path)?; let current_content : Vec = serde_json::from_str(&file_content)?; let mut out = Vec::new(); for sugg in current_content.iter().rev().skip(offset) {