You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2024/07/03 15:45:18 UTC

(opendal) branch main updated: feat(services/fs): Support fs config (#4853)

This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 174bda53f7 feat(services/fs): Support fs config (#4853)
174bda53f7 is described below

commit 174bda53f79123cd114d2409189423a0a4cf6bf3
Author: meteorgan <me...@gmail.com>
AuthorDate: Wed Jul 3 23:44:37 2024 +0800

    feat(services/fs): Support fs config (#4853)
    
    feat(services-fs): support fs config
---
 core/src/services/fs/backend.rs | 57 ++++++++++++++++++++++-------------------
 core/src/services/fs/mod.rs     |  1 +
 core/src/services/mod.rs        |  2 ++
 3 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs
index 89f2c1ca68..9c8d5b911f 100644
--- a/core/src/services/fs/backend.rs
+++ b/core/src/services/fs/backend.rs
@@ -23,30 +23,41 @@ use std::sync::Arc;
 
 use chrono::DateTime;
 use log::debug;
+use serde::Deserialize;
+
+use crate::raw::*;
+use crate::*;
 
 use super::core::*;
 use super::lister::FsLister;
 use super::reader::FsReader;
 use super::writer::FsWriter;
-use crate::raw::*;
-use crate::*;
+
+/// config for file system
+#[derive(Default, Deserialize, Debug)]
+#[serde(default)]
+#[non_exhaustive]
+pub struct FsConfig {
+    /// root dir for backend
+    pub root: Option<String>,
+
+    /// tmp dir for atomic write
+    pub atomic_write_dir: Option<String>,
+}
 
 /// POSIX file system support.
 #[doc = include_str!("docs.md")]
 #[derive(Default, Debug)]
 pub struct FsBuilder {
-    root: Option<PathBuf>,
-    atomic_write_dir: Option<PathBuf>,
+    config: FsConfig,
 }
 
 impl FsBuilder {
     /// Set root for backend.
     pub fn root(&mut self, root: &str) -> &mut Self {
-        self.root = if root.is_empty() {
-            None
-        } else {
-            Some(PathBuf::from(root))
-        };
+        if !root.is_empty() {
+            self.config.root = Some(root.to_string());
+        }
 
         self
     }
@@ -58,11 +69,9 @@ impl FsBuilder {
     /// - When append is enabled, we will not use atomic write
     /// to avoid data loss and performance issue.
     pub fn atomic_write_dir(&mut self, dir: &str) -> &mut Self {
-        self.atomic_write_dir = if dir.is_empty() {
-            None
-        } else {
-            Some(PathBuf::from(dir))
-        };
+        if !dir.is_empty() {
+            self.config.atomic_write_dir = Some(dir.to_string());
+        }
 
         self
     }
@@ -73,19 +82,15 @@ impl Builder for FsBuilder {
     type Accessor = FsBackend;
 
     fn from_map(map: HashMap<String, String>) -> Self {
-        let mut builder = FsBuilder::default();
-
-        map.get("root").map(|v| builder.root(v));
-        map.get("atomic_write_dir")
-            .map(|v| builder.atomic_write_dir(v));
-
-        builder
+        let config = FsConfig::deserialize(ConfigDeserializer::new(map))
+            .expect("config deserialize must succeed");
+        FsBuilder { config }
     }
 
     fn build(&mut self) -> Result<Self::Accessor> {
         debug!("backend build started: {:?}", &self);
 
-        let root = match self.root.take() {
+        let root = match self.config.root.take().map(PathBuf::from) {
             Some(root) => Ok(root),
             None => Err(Error::new(
                 ErrorKind::ConfigInvalid,
@@ -106,7 +111,7 @@ impl Builder for FsBuilder {
             }
         }
 
-        let atomic_write_dir = self.atomic_write_dir.take();
+        let atomic_write_dir = self.config.atomic_write_dir.take().map(PathBuf::from);
 
         // If atomic write dir is not exist, we must create it.
         if let Some(d) = &atomic_write_dir {
@@ -240,9 +245,9 @@ impl Access for FsBackend {
     ///
     /// There are three ways to get the total file length:
     ///
-    /// - call std::fs::metadata directly and than open. (400ns)
-    /// - open file first, and than use `f.metadata()` (300ns)
-    /// - open file first, and than use `seek`. (100ns)
+    /// - call std::fs::metadata directly and then open. (400ns)
+    /// - open file first, and then use `f.metadata()` (300ns)
+    /// - open file first, and then use `seek`. (100ns)
     ///
     /// Benchmark could be found [here](https://gist.github.com/Xuanwo/48f9cfbc3022ea5f865388bb62e1a70f)
     async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
diff --git a/core/src/services/fs/mod.rs b/core/src/services/fs/mod.rs
index a597690c19..6ffe4896a8 100644
--- a/core/src/services/fs/mod.rs
+++ b/core/src/services/fs/mod.rs
@@ -17,6 +17,7 @@
 
 mod backend;
 pub use backend::FsBuilder as Fs;
+pub use backend::FsConfig;
 
 mod core;
 mod lister;
diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs
index 65d9bf30fc..f6e7c15931 100644
--- a/core/src/services/mod.rs
+++ b/core/src/services/mod.rs
@@ -64,6 +64,8 @@ pub use self::etcd::EtcdConfig;
 mod fs;
 #[cfg(feature = "services-fs")]
 pub use fs::Fs;
+#[cfg(feature = "services-fs")]
+pub use fs::FsConfig;
 
 #[cfg(feature = "services-ftp")]
 mod ftp;