From c24608e1e1e609a20eb3093b930911d4501abcbe Mon Sep 17 00:00:00 2001 From: ffranzgitHub Date: Fri, 10 Jan 2025 23:10:43 +0100 Subject: [PATCH 1/3] implemented in memory Filesystem --- rust/backend/daemon/src/filesystem/memory.rs | 35 ++++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/rust/backend/daemon/src/filesystem/memory.rs b/rust/backend/daemon/src/filesystem/memory.rs index 6307eeeb..113c3b28 100644 --- a/rust/backend/daemon/src/filesystem/memory.rs +++ b/rust/backend/daemon/src/filesystem/memory.rs @@ -4,19 +4,40 @@ use std::io; +use std::collections::HashMap; +use tokio::sync::RwLock; + use shared::config::Configuration; use super::Filesystem; -// TODO: members + implementation -pub struct MemoryFilesystem; +pub struct MemoryFilesystem { + storage: RwLock>, +} + +impl MemoryFilesystem { + pub fn new() -> Self { + MemoryFilesystem { + storage: RwLock::new(HashMap::new()), + } + } +} impl Filesystem for MemoryFilesystem { - fn load(&self, _path: &str) -> io::Result { - todo!() + fn load(&self, path: &str) -> io::Result { + tokio::task::block_in_place(|| { + let storage = self.storage.blocking_read(); + storage.get(path).cloned().ok_or_else(|| { + io::Error::new(io::ErrorKind::NotFound, "Configuration not found") + }) + }) } - fn save(&self, _config: &Configuration, _path: &str) -> io::Result<()> { - todo!() + fn save(&self, config: &Configuration, path: &str) -> io::Result<()> { + tokio::task::block_in_place(|| { + let mut storage = self.storage.blocking_write(); + storage.insert(path.to_string(), config.clone()); + Ok(()) + }) } -} \ No newline at end of file +} From ce47c0bcccbf5977717abf182477bec2327e05c4 Mon Sep 17 00:00:00 2001 From: ffranzgitHub Date: Sun, 26 Jan 2025 21:58:28 +0100 Subject: [PATCH 2/3] made async and made names more fitting --- rust/backend/daemon/src/filesystem/memory.rs | 14 ++++++------ rust/backend/daemon/src/filesystem/mod.rs | 24 +++++++------------- rust/backend/daemon/src/filesystem/normal.rs | 10 ++++---- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/rust/backend/daemon/src/filesystem/memory.rs b/rust/backend/daemon/src/filesystem/memory.rs index 113c3b28..f8964ee5 100644 --- a/rust/backend/daemon/src/filesystem/memory.rs +++ b/rust/backend/daemon/src/filesystem/memory.rs @@ -9,22 +9,22 @@ use tokio::sync::RwLock; use shared::config::Configuration; -use super::Filesystem; +use super::ConfigurationStorage; -pub struct MemoryFilesystem { +pub struct MemoryConfigurationStorage { storage: RwLock>, } -impl MemoryFilesystem { +impl MemoryConfigurationStorage { pub fn new() -> Self { - MemoryFilesystem { + MemoryConfigurationStorage { storage: RwLock::new(HashMap::new()), } } } -impl Filesystem for MemoryFilesystem { - fn load(&self, path: &str) -> io::Result { +impl ConfigurationStorage for MemoryConfigurationStorage { + async fn load(&self, path: &str) -> io::Result { tokio::task::block_in_place(|| { let storage = self.storage.blocking_read(); storage.get(path).cloned().ok_or_else(|| { @@ -33,7 +33,7 @@ impl Filesystem for MemoryFilesystem { }) } - fn save(&self, config: &Configuration, path: &str) -> io::Result<()> { + async fn save(&self, config: &Configuration, path: &str) -> io::Result<()> { tokio::task::block_in_place(|| { let mut storage = self.storage.blocking_write(); storage.insert(path.to_string(), config.clone()); diff --git a/rust/backend/daemon/src/filesystem/mod.rs b/rust/backend/daemon/src/filesystem/mod.rs index 4d22069a..03008a12 100644 --- a/rust/backend/daemon/src/filesystem/mod.rs +++ b/rust/backend/daemon/src/filesystem/mod.rs @@ -10,21 +10,13 @@ use shared::config::Configuration; mod normal; mod memory; -pub use normal::NormalFilesystem; - -// TODO: pub use memory::MemoryFilesystem; - -/* - * TODOs: - * - This should probably not be named Filesystem, because the functionality is much more narrow - * than that. Maybe something like ConfigurationStore or ConfigurationStorage? - * - The trait should definetly be async, because otherwise we always have to use spawn_blocking. - * See the tokio documentation for why: https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html - * You can use tokio::fs for file system operations. - */ -pub trait Filesystem: Send + Sync + 'static { - fn load(&self, path: &str) -> io::Result; - - fn save(&self, config: &Configuration, path: &str) -> io::Result<()>; +pub use normal::NormalConfigurationStorage; + +pub use memory::MemoryConfigurationStorage; + +pub trait ConfigurationStorage: Send + Sync + 'static { + async fn load(&self, path: &str) -> io::Result; + + async fn save(&self, config: &Configuration, path: &str) -> io::Result<()>; } diff --git a/rust/backend/daemon/src/filesystem/normal.rs b/rust/backend/daemon/src/filesystem/normal.rs index 94b3d62f..2be39919 100644 --- a/rust/backend/daemon/src/filesystem/normal.rs +++ b/rust/backend/daemon/src/filesystem/normal.rs @@ -6,20 +6,20 @@ use std::{fs::File, io::{self, BufReader, BufWriter}}; use shared::config::Configuration; -use super::Filesystem; +use super::ConfigurationStorage; -pub struct NormalFilesystem; +pub struct NormalConfigurationStorage; -impl Filesystem for NormalFilesystem { - fn load(&self, path: &str) -> io::Result { +impl ConfigurationStorage for NormalConfigurationStorage { + async fn load(&self, path: &str) -> io::Result { let file = File::open(path)?; let reader = BufReader::new(file); let config = serde_json::from_reader(reader)?; Ok(config) } - fn save(&self, config: &Configuration, path: &str) -> io::Result<()> { + async fn save(&self, config: &Configuration, path: &str) -> io::Result<()> { let file = File::create(path)?; let writer = BufWriter::new(file); serde_json::to_writer(writer, config)?; From 824aeb98fb99b71958103583718c4698a39b2896 Mon Sep 17 00:00:00 2001 From: ffranzgitHub Date: Sun, 26 Jan 2025 22:28:10 +0100 Subject: [PATCH 3/3] resolved async/send type problems --- rust/backend/daemon/src/filesystem/mod.rs | 5 ++-- rust/backend/daemon/src/server.rs | 29 ++++++++++++----------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/rust/backend/daemon/src/filesystem/mod.rs b/rust/backend/daemon/src/filesystem/mod.rs index 03008a12..213057a3 100644 --- a/rust/backend/daemon/src/filesystem/mod.rs +++ b/rust/backend/daemon/src/filesystem/mod.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT use std::io; +use std::future::Future; use shared::config::Configuration; @@ -15,8 +16,8 @@ pub use normal::NormalConfigurationStorage; pub use memory::MemoryConfigurationStorage; pub trait ConfigurationStorage: Send + Sync + 'static { - async fn load(&self, path: &str) -> io::Result; + fn load(&self, path: &str) -> impl Future> + Send ; - async fn save(&self, config: &Configuration, path: &str) -> io::Result<()>; + fn save(&self, config: &Configuration, path: &str) -> impl Future> + Send ; } diff --git a/rust/backend/daemon/src/server.rs b/rust/backend/daemon/src/server.rs index 08f755c3..4df0beff 100644 --- a/rust/backend/daemon/src/server.rs +++ b/rust/backend/daemon/src/server.rs @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT use crate::collector::{CollectorSupervisor, CollectorSupervisorArguments}; -use crate::filesystem::{Filesystem, NormalFilesystem}; +use crate::filesystem::{ConfigurationStorage, NormalConfigurationStorage}; use crate::registry; use crate::symbols::SymbolHandler; use crate::{ @@ -31,27 +31,27 @@ use tokio::sync::{mpsc, Mutex}; use tokio_stream::wrappers::ReceiverStream; use tonic::{transport::Server, Request, Response, Status}; -pub struct ZiofaImpl -where F: Filesystem { +pub struct ZiofaImpl +where C: ConfigurationStorage { features: Arc>, channel: Arc, symbol_handler: Arc>, - filesystem: F, + configuration_storage: C, } -impl ZiofaImpl -where F: Filesystem { +impl ZiofaImpl +where C: ConfigurationStorage { pub fn new( features: Arc>, channel: Arc, symbol_handler: Arc>, - filesystem: F, - ) -> ZiofaImpl { + configuration_storage: C, + ) -> ZiofaImpl { ZiofaImpl { features, channel, symbol_handler, - filesystem + configuration_storage } } } @@ -69,8 +69,8 @@ impl Channel { } #[tonic::async_trait] -impl Ziofa for ZiofaImpl -where F: Filesystem { +impl Ziofa for ZiofaImpl +where C: ConfigurationStorage { async fn check_server(&self, _: Request<()>) -> Result, Status> { // dummy data let response = CheckServerResponse {}; @@ -84,7 +84,8 @@ where F: Filesystem { async fn get_configuration(&self, _: Request<()>) -> Result, Status> { //TODO: if ? fails needs valid return value for the function so that the server doesn't crash. - let config = self.filesystem.load(constants::DEV_DEFAULT_FILE_PATH)?; + let res = self.configuration_storage.load(constants::DEV_DEFAULT_FILE_PATH).await; + let config = res?; Ok(Response::new(config)) } @@ -94,7 +95,7 @@ where F: Filesystem { ) -> Result, Status> { let config = request.into_inner(); - self.filesystem.save(&config, constants::DEV_DEFAULT_FILE_PATH)?; + self.configuration_storage.save(&config, constants::DEV_DEFAULT_FILE_PATH).await?; let mut features_guard = self.features.lock().await; @@ -250,7 +251,7 @@ pub async fn serve_forever() { let features = Arc::new(Mutex::new(features)); - let filesystem = NormalFilesystem; + let filesystem = NormalConfigurationStorage; let ziofa_server = ZiofaServer::new(ZiofaImpl::new(features, channel, symbol_handler, filesystem));