This is an automated email from the ASF dual-hosted git repository. koushiro pushed a commit to branch unify-layers in repository https://gitbox.apache.org/repos/asf/opendal.git
commit 42e6f18546b08b0bbff8f736f7ad80b8f0adc68b Author: koushiro <[email protected]> AuthorDate: Wed Dec 24 23:44:20 2025 +0800 chore(layers): unify layer crates and gate dtrace on linux - add crate-level docs, doc_cfg, and missing_docs lint across layer crates - mark layers non_exhaustive and hide internal accessors/wrappers - move dtrace dependency to linux target and tidy Cargo.toml/workspace dependency specs --- core/Cargo.lock | 1 + core/Cargo.toml | 4 +- .../core/src/docs/performance/http_optimization.md | 2 +- core/core/src/docs/upgrade.md | 13 ++-- core/layers/async-backtrace/src/lib.rs | 38 ++++++---- core/layers/await-tree/src/lib.rs | 25 ++++--- core/layers/capability-check/src/lib.rs | 52 ++++++++------ core/layers/chaos/src/lib.rs | 23 +++--- core/layers/concurrent-limit/src/lib.rs | 27 ++++--- core/layers/dtrace/Cargo.toml | 7 +- core/layers/dtrace/src/lib.rs | 42 +++++++---- core/layers/fastmetrics/Cargo.toml | 2 +- core/layers/fastmetrics/src/lib.rs | 14 ++-- core/layers/fastrace/src/lib.rs | 23 ++++-- core/layers/hotpath/src/lib.rs | 24 +++++-- core/layers/immutable-index/src/lib.rs | 23 ++++-- core/layers/logging/src/lib.rs | 16 ++++- core/layers/metrics/src/lib.rs | 20 +++++- core/layers/mime-guess/src/lib.rs | 65 +++++++++-------- core/layers/observe-metrics-common/Cargo.toml | 5 +- core/layers/observe-metrics-common/src/lib.rs | 35 ++++----- core/layers/otelmetrics/Cargo.toml | 2 +- core/layers/otelmetrics/src/lib.rs | 8 ++- core/layers/oteltrace/src/lib.rs | 20 +++++- core/layers/prometheus-client/Cargo.toml | 2 +- core/layers/prometheus-client/src/lib.rs | 19 ++--- core/layers/prometheus/Cargo.toml | 2 +- core/layers/prometheus/src/lib.rs | 22 +++--- core/layers/retry/Cargo.toml | 6 +- core/layers/retry/src/lib.rs | 82 ++++++++++------------ core/layers/tail-cut/src/lib.rs | 35 ++++----- core/layers/throttle/Cargo.toml | 2 +- core/layers/throttle/src/lib.rs | 22 +++--- core/layers/timeout/Cargo.toml | 2 +- core/layers/timeout/src/lib.rs | 32 +++++---- core/layers/tracing/src/lib.rs | 46 +++++++----- 36 files changed, 471 insertions(+), 292 deletions(-) diff --git a/core/Cargo.lock b/core/Cargo.lock index 852e81b01..f9ad9f2f2 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -5782,6 +5782,7 @@ dependencies = [ "bytes", "opendal-core", "probe", + "tokio", ] [[package]] diff --git a/core/Cargo.toml b/core/Cargo.toml index f3f58c972..12caac5c0 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -207,7 +207,6 @@ opendal-layer-await-tree = { path = "layers/await-tree", version = "0.55.0", opt opendal-layer-capability-check = { path = "layers/capability-check", version = "0.55.0", optional = true, default-features = false } opendal-layer-chaos = { path = "layers/chaos", version = "0.55.0", optional = true, default-features = false } opendal-layer-concurrent-limit = { path = "layers/concurrent-limit", version = "0.55.0", optional = true, default-features = false } -opendal-layer-dtrace = { path = "layers/dtrace", version = "0.55.0", optional = true, default-features = false } opendal-layer-fastmetrics = { path = "layers/fastmetrics", version = "0.55.0", optional = true, default-features = false } opendal-layer-fastrace = { path = "layers/fastrace", version = "0.55.0", optional = true, default-features = false } opendal-layer-hotpath = { path = "layers/hotpath", version = "0.55.0", optional = true, default-features = false } @@ -287,6 +286,9 @@ opendal-service-webhdfs = { path = "services/webhdfs", version = "0.55.0", optio opendal-service-yandex-disk = { path = "services/yandex-disk", version = "0.55.0", optional = true, default-features = false } opendal-testkit = { path = "testkit", version = "0.55.0", optional = true } +[target.'cfg(target_os = "linux")'.dependencies] +opendal-layer-dtrace = { path = "layers/dtrace", version = "0.55.0", optional = true, default-features = false } + [target.'cfg(target_arch = "wasm32")'.dependencies] opendal-service-opfs = { path = "services/opfs", version = "0.55.0", optional = true, default-features = false } diff --git a/core/core/src/docs/performance/http_optimization.md b/core/core/src/docs/performance/http_optimization.md index 95aa84dbc..83e2b6df5 100644 --- a/core/core/src/docs/performance/http_optimization.md +++ b/core/core/src/docs/performance/http_optimization.md @@ -93,7 +93,7 @@ In addition to the options mentioned above, `Xuanwo/reqwest-hickory-resolver` al `reqwest` didn't set a default timeout for HTTP requests. This means that if a request hangs or takes too long to complete, it can block the entire process, leading to performance degradation or even application crashes. -It's recommended to set a connect timeout for HTTP requests to prevent this issue. +It's recommended to set a connect timeout for HTTP requests to prevent this issue. ```rust let client = reqwest::ClientBuilder::new() diff --git a/core/core/src/docs/upgrade.md b/core/core/src/docs/upgrade.md index 53654435f..ae1e8aeb7 100644 --- a/core/core/src/docs/upgrade.md +++ b/core/core/src/docs/upgrade.md @@ -56,7 +56,7 @@ OpenDAL v0.54 implements [RFC-6213](https://opendal.apache.org/docs/rust/opendal New APIs added: - `read_options(path, ReadOptions)` -- `write_options(path, data, WriteOptions)` +- `write_options(path, data, WriteOptions)` - `list_options(path, ListOptions)` - `stat_options(path, StatOptions)` - `delete_options(path, DeleteOptions)` @@ -70,7 +70,7 @@ let options = ReadOptions::new() .if_match("etag"); let data = op.read_options("path/to/file", options).await?; -// Write with options +// Write with options let options = WriteOptions::new() .content_type("text/plain") .cache_control("max-age=3600"); @@ -118,7 +118,7 @@ New options-based presign APIs have been exposed: ```rust let options = PresignOptions::new() .expire(Duration::from_secs(3600)); - + let url = op.presign_read_options("path/to/file", options).await?; ``` @@ -171,7 +171,6 @@ For example: - `Operation::ReaderRead` has been merged into `Operation::Read` - `Operation::BlockingRead` has been merged into `Operation::Read` - # Upgrade to v0.52 ## Public API @@ -636,7 +635,7 @@ After [RFC: List Prefix](crate::docs::rfcs::rfc_3243_list_prefix) landed, we hav Here are the behavior list: | Case | Path | Result | -|------------------------|-----------------|--------------------------------------------| +| ---------------------- | --------------- | ------------------------------------------ | | stat existing dir | `abc/` | Metadata with dir mode | | stat existing file | `abc/def_file` | Metadata with file mode | | stat dir without `/` | `abc/def_dir` | Error `NotFound` or metadata with dir mode | @@ -773,8 +772,6 @@ OpenDAL v0.40 removed the origin `range_read` and `range_reader` interfaces, ple + let reader = op.reader_with(path).range(range_start..range_end).await?; ``` - - ## Raw API ### RFC-3017 Remove Write Copy From @@ -962,7 +959,7 @@ More details could be found at [RFC: Remove Object Concept][crate::docs::rfcs::r To upgrade to OpenDAL v0.30, users need to make the following changes: - regex replace `object\((.*)\).reader\(\)` to `reader($1)` - - replace the function on your case, it's recommended to do it one by one + - replace the function on your case, it's recommended to do it one by one - rename `ObjectMetakey` => `Metakey` - rename `ObjectMode` => `EntryMode` - replace `ErrorKind::ObjectXxx` to `ErrorKind::Xxx` diff --git a/core/layers/async-backtrace/src/lib.rs b/core/layers/async-backtrace/src/lib.rs index 2f9d67f58..f8222097a 100644 --- a/core/layers/async-backtrace/src/lib.rs +++ b/core/layers/async-backtrace/src/lib.rs @@ -15,7 +15,11 @@ // specific language governing permissions and limitations // under the License. -use opendal_core::raw::oio; +//! Async backtrace layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use opendal_core::raw::*; use opendal_core::*; @@ -29,30 +33,39 @@ use opendal_core::*; /// # Examples /// /// ```no_run -/// use opendal_layer_async_backtrace::AsyncBacktraceLayer; -/// use opendal_core::services; -/// use opendal_core::Operator; -/// use opendal_core::Result; -/// +/// # use opendal_core::services; +/// # use opendal_core::Operator; +/// # use opendal_core::Result; +/// # use opendal_layer_async_backtrace::AsyncBacktraceLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(AsyncBacktraceLayer::default()) +/// .layer(AsyncBacktraceLayer::new()) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` #[derive(Clone, Default)] -pub struct AsyncBacktraceLayer; +#[non_exhaustive] +pub struct AsyncBacktraceLayer {} + +impl AsyncBacktraceLayer { + /// Create a new [`AsyncBacktraceLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for AsyncBacktraceLayer { type LayeredAccess = AsyncBacktraceAccessor<A>; - fn layer(&self, accessor: A) -> Self::LayeredAccess { - AsyncBacktraceAccessor { inner: accessor } + fn layer(&self, inner: A) -> Self::LayeredAccess { + AsyncBacktraceAccessor { inner } } } -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct AsyncBacktraceAccessor<A: Access> { inner: A, } @@ -121,6 +134,7 @@ impl<A: Access> LayeredAccess for AsyncBacktraceAccessor<A> { } } +#[doc(hidden)] pub struct AsyncBacktraceWrapper<R> { inner: R, } diff --git a/core/layers/await-tree/src/lib.rs b/core/layers/await-tree/src/lib.rs index b17eec518..1b98de408 100644 --- a/core/layers/await-tree/src/lib.rs +++ b/core/layers/await-tree/src/lib.rs @@ -15,9 +15,13 @@ // specific language governing permissions and limitations // under the License. +//! Await tree layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use await_tree::InstrumentAwait; use futures::Future; - use opendal_core::raw::*; use opendal_core::*; @@ -32,37 +36,39 @@ use opendal_core::*; /// # Examples /// /// ```no_run -/// # use opendal_layer_await_tree::AwaitTreeLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_await_tree::AwaitTreeLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? /// .layer(AwaitTreeLayer::new()) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` #[derive(Clone, Default)] +#[non_exhaustive] pub struct AwaitTreeLayer {} impl AwaitTreeLayer { - /// Create a new `AwaitTreeLayer`. + /// Create a new [`AwaitTreeLayer`]. pub fn new() -> Self { - Self {} + Self::default() } } impl<A: Access> Layer<A> for AwaitTreeLayer { type LayeredAccess = AwaitTreeAccessor<A>; - fn layer(&self, accessor: A) -> Self::LayeredAccess { - AwaitTreeAccessor { inner: accessor } + fn layer(&self, inner: A) -> Self::LayeredAccess { + AwaitTreeAccessor { inner } } } -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct AwaitTreeAccessor<A: Access> { inner: A, } @@ -139,6 +145,7 @@ impl<A: Access> LayeredAccess for AwaitTreeAccessor<A> { } } +#[doc(hidden)] pub struct AwaitTreeWrapper<R> { inner: R, } diff --git a/core/layers/capability-check/src/lib.rs b/core/layers/capability-check/src/lib.rs index 5d09ef1ae..b0ba046f0 100644 --- a/core/layers/capability-check/src/lib.rs +++ b/core/layers/capability-check/src/lib.rs @@ -15,12 +15,17 @@ // specific language governing permissions and limitations // under the License. +//! Capability check layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; use std::fmt::Formatter; use std::sync::Arc; use opendal_core::raw::*; -use opendal_core::{Error, ErrorKind, Result}; +use opendal_core::*; /// Add an extra capability check layer for every operation /// @@ -38,24 +43,31 @@ use opendal_core::{Error, ErrorKind, Result}; /// 2. OpenDAL doesn't apply this checker by default. Users can enable this layer if they want to /// enforce stricter requirements. /// -/// # examples +/// # Examples /// /// ```no_run -/// # use opendal_layer_capability_check::CapabilityCheckLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_capability_check::CapabilityCheckLayer; +/// # /// # fn main() -> Result<()> { -/// use opendal_layer_capability_check::CapabilityCheckLayer; /// let _ = Operator::new(services::Memory::default())? -/// .layer(CapabilityCheckLayer) +/// .layer(CapabilityCheckLayer::new()) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` -#[derive(Default)] -pub struct CapabilityCheckLayer; +#[derive(Clone, Default)] +#[non_exhaustive] +pub struct CapabilityCheckLayer {} + +impl CapabilityCheckLayer { + /// Create a new [`CapabilityCheckLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for CapabilityCheckLayer { type LayeredAccess = CapabilityAccessor<A>; @@ -67,11 +79,20 @@ impl<A: Access> Layer<A> for CapabilityCheckLayer { } } +#[doc(hidden)] pub struct CapabilityAccessor<A: Access> { info: Arc<AccessorInfo>, inner: A, } +impl<A: Access> Debug for CapabilityAccessor<A> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CapabilityCheckAccessor") + .field("inner", &self.inner) + .finish_non_exhaustive() + } +} + fn new_unsupported_error(info: &AccessorInfo, op: Operation, args: &str) -> Error { let scheme = info.scheme(); let op = op.into_static(); @@ -83,14 +104,6 @@ fn new_unsupported_error(info: &AccessorInfo, op: Operation, args: &str) -> Erro .with_operation(op) } -impl<A: Access> Debug for CapabilityAccessor<A> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("CapabilityCheckAccessor") - .field("inner", &self.inner) - .finish_non_exhaustive() - } -} - impl<A: Access> LayeredAccess for CapabilityAccessor<A> { type Inner = A; type Reader = A::Reader; @@ -154,9 +167,6 @@ impl<A: Access> LayeredAccess for CapabilityAccessor<A> { #[cfg(test)] mod tests { use super::*; - use opendal_core::Capability; - use opendal_core::ErrorKind; - use opendal_core::Operator; #[derive(Debug)] struct MockService { @@ -188,7 +198,7 @@ mod tests { fn new_test_operator(capability: Capability) -> Operator { let srv = MockService { capability }; - Operator::from_inner(Arc::new(srv)).layer(CapabilityCheckLayer) + Operator::from_inner(Arc::new(srv)).layer(CapabilityCheckLayer::new()) } #[tokio::test] diff --git a/core/layers/chaos/src/lib.rs b/core/layers/chaos/src/lib.rs index 9334b7917..f9c82b1ea 100644 --- a/core/layers/chaos/src/lib.rs +++ b/core/layers/chaos/src/lib.rs @@ -15,14 +15,18 @@ // specific language governing permissions and limitations // under the License. +//! Chaos layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::sync::Arc; use std::sync::Mutex; -use rand::prelude::*; -use rand::rngs::StdRng; - use opendal_core::raw::*; use opendal_core::*; +use rand::prelude::*; +use rand::rngs::StdRng; /// Inject chaos into underlying services for robustness test. /// @@ -44,25 +48,25 @@ use opendal_core::*; /// # Examples /// /// ```no_run -/// # use opendal_layer_chaos::ChaosLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_chaos::ChaosLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? /// .layer(ChaosLayer::new(0.1)) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct ChaosLayer { error_ratio: f64, } impl ChaosLayer { - /// Create a new chaos layer with specified error ratio. + /// Create a new [`ChaosLayer`] with specified error ratio. /// /// # Panics /// @@ -88,6 +92,7 @@ impl<A: Access> Layer<A> for ChaosLayer { } } +#[doc(hidden)] #[derive(Debug)] pub struct ChaosAccessor<A> { inner: A, @@ -127,7 +132,7 @@ impl<A: Access> LayeredAccess for ChaosAccessor<A> { } } -/// ChaosReader will inject error into read operations. +#[doc(hidden)] pub struct ChaosReader<R> { inner: R, rng: Arc<Mutex<StdRng>>, diff --git a/core/layers/concurrent-limit/src/lib.rs b/core/layers/concurrent-limit/src/lib.rs index bde32113e..53c15b208 100644 --- a/core/layers/concurrent-limit/src/lib.rs +++ b/core/layers/concurrent-limit/src/lib.rs @@ -15,7 +15,11 @@ // specific language governing permissions and limitations // under the License. -use std::fmt::Debug; +//! Concurrent request limit layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::pin::Pin; use std::sync::Arc; use std::task::Context; @@ -25,7 +29,6 @@ use futures::Stream; use futures::StreamExt; use mea::semaphore::OwnedSemaphorePermit; use mea::semaphore::Semaphore; - use opendal_core::raw::*; use opendal_core::*; @@ -46,27 +49,27 @@ use opendal_core::*; /// Add a concurrent limit layer to the operator: /// /// ```no_run -/// # use opendal_layer_concurrent_limit::ConcurrentLimitLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_concurrent_limit::ConcurrentLimitLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? /// .layer(ConcurrentLimitLayer::new(1024)) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` /// /// Share a concurrent limit layer between the operators: /// /// ```no_run -/// # use opendal_layer_concurrent_limit::ConcurrentLimitLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_concurrent_limit::ConcurrentLimitLayer; +/// # /// # fn main() -> Result<()> { /// let limit = ConcurrentLimitLayer::new(1024); /// @@ -76,8 +79,7 @@ use opendal_core::*; /// let _operator_b = Operator::new(services::Memory::default())? /// .layer(limit.clone()) /// .finish(); -/// -/// Ok(()) +/// # Ok(()) /// # } /// ``` #[derive(Clone)] @@ -128,6 +130,7 @@ impl<A: Access> Layer<A> for ConcurrentLimitLayer { } } +#[doc(hidden)] pub struct ConcurrentLimitHttpFetcher { inner: HttpFetcher, http_semaphore: Option<Arc<Semaphore>>, @@ -153,7 +156,7 @@ impl HttpFetch for ConcurrentLimitHttpFetcher { } } -pub struct ConcurrentLimitStream<S> { +struct ConcurrentLimitStream<S> { inner: S, // Hold on this permit until this reader has been dropped. _permit: OwnedSemaphorePermit, @@ -170,7 +173,8 @@ where } } -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct ConcurrentLimitAccessor<A: Access> { inner: A, semaphore: Arc<Semaphore>, @@ -236,6 +240,7 @@ impl<A: Access> LayeredAccess for ConcurrentLimitAccessor<A> { } } +#[doc(hidden)] pub struct ConcurrentLimitWrapper<R> { inner: R, diff --git a/core/layers/dtrace/Cargo.toml b/core/layers/dtrace/Cargo.toml index 3db823637..0f6153630 100644 --- a/core/layers/dtrace/Cargo.toml +++ b/core/layers/dtrace/Cargo.toml @@ -30,10 +30,11 @@ version = { workspace = true } [package.metadata.docs.rs] all-features = true -[dependencies] +[target.'cfg(target_os = "linux")'.dependencies] bytes = { workspace = true } opendal-core = { path = "../../core", version = "0.55.0", default-features = false } -probe = { version = "0.5.1" } +probe = "0.5.1" -[dev-dependencies] +[target.'cfg(target_os = "linux")'.dev-dependencies] opendal-core = { path = "../../core", version = "0.55.0" } +tokio = { workspace = true, features = ["macros", "rt-multi-thread"]} diff --git a/core/layers/dtrace/src/lib.rs b/core/layers/dtrace/src/lib.rs index c0c292f1a..adaa98ea6 100644 --- a/core/layers/dtrace/src/lib.rs +++ b/core/layers/dtrace/src/lib.rs @@ -15,16 +15,20 @@ // specific language governing permissions and limitations // under the License. +//! Dtrace layer implementation for Apache OpenDAL. + +#![cfg(target_os = "linux")] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::ffi::CString; use std::fmt::Debug; use std::fmt::Formatter; use bytes::Buf; -use probe::probe_lazy; - -use opendal_core::raw::Access; use opendal_core::raw::*; use opendal_core::*; +use probe::probe_lazy; /// Support User Statically-Defined Tracing(aka USDT) on Linux /// @@ -72,17 +76,17 @@ use opendal_core::*; /// /// Example: /// -/// ```ignore -/// # use opendal::layers::DtraceLayer; -/// # use opendal::services; -/// # use opendal::Operator; -/// # use opendal::Result; -/// +/// ```no_run +/// # use opendal_core::services; +/// # use opendal_core::Operator; +/// # use opendal_core::Result; +/// # use opendal_layer_dtrace::DtraceLayer; +/// # /// # #[tokio::main] /// # async fn main() -> Result<()> { /// // `Accessor` provides the low level APIs, we will use `Operator` normally. -/// let op: Operator = Operator::new(services::Fs::default().root("/tmp"))? -/// .layer(DtraceLayer::default()) +/// let op: Operator = Operator::new(services::Memory::default().root("/tmp"))? +/// .layer(DtraceLayer::new()) /// .finish(); /// /// let path = "/tmp/test.txt"; @@ -91,7 +95,7 @@ use opendal_core::*; /// op.write(path, bs).await?; /// op.read(path).await?; /// } -/// Ok(()) +/// # Ok(()) /// # } /// ``` /// @@ -122,9 +126,16 @@ use opendal_core::*; /// Arguments: -8@%rax /// stapsdt 0x0000003c NT_STAPSDT (SystemTap probe descriptors) /// ``` -#[derive(Default, Debug, Clone)] +#[derive(Clone, Default)] +#[non_exhaustive] pub struct DtraceLayer {} +impl DtraceLayer { + pub fn new() -> Self { + Self::default() + } +} + impl<A: Access> Layer<A> for DtraceLayer { type LayeredAccess = DTraceAccessor<A>; fn layer(&self, inner: A) -> Self::LayeredAccess { @@ -132,7 +143,7 @@ impl<A: Access> Layer<A> for DtraceLayer { } } -#[derive(Clone)] +#[doc(hidden)] pub struct DTraceAccessor<A: Access> { inner: A, } @@ -218,13 +229,14 @@ impl<A: Access> LayeredAccess for DTraceAccessor<A> { } } +#[doc(hidden)] pub struct DtraceLayerWrapper<R> { inner: R, path: String, } impl<R> DtraceLayerWrapper<R> { - pub fn new(inner: R, path: &String) -> Self { + fn new(inner: R, path: &String) -> Self { Self { inner, path: path.to_string(), diff --git a/core/layers/fastmetrics/Cargo.toml b/core/layers/fastmetrics/Cargo.toml index fc9b43fc1..65fb4e36f 100644 --- a/core/layers/fastmetrics/Cargo.toml +++ b/core/layers/fastmetrics/Cargo.toml @@ -31,7 +31,7 @@ version = { workspace = true } all-features = true [dependencies] -fastmetrics = { version = "0.4.1" } +fastmetrics = "0.4.1" opendal-core = { path = "../../core", version = "0.55.0", default-features = false } opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0", default-features = false } diff --git a/core/layers/fastmetrics/src/lib.rs b/core/layers/fastmetrics/src/lib.rs index bf39d055b..3c6435748 100644 --- a/core/layers/fastmetrics/src/lib.rs +++ b/core/layers/fastmetrics/src/lib.rs @@ -15,7 +15,10 @@ // specific language governing permissions and limitations // under the License. -use std::fmt; +//! Metrics layer (using the [fastmetrics](https://docs.rs/fastmetrics/) crate) implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] use fastmetrics::encoder::EncodeLabelSet; use fastmetrics::encoder::LabelSetEncoder; @@ -124,7 +127,7 @@ use opendal_layer_observe_metrics_common as observe; /// println!("{}", output); /// # Ok(()) /// # } -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct FastmetricsLayer { interceptor: FastmetricsInterceptor, } @@ -324,11 +327,11 @@ impl FastmetricsLayerBuilder { /// # Example /// /// ```no_run - /// # use opendal_layer_fastmetrics::FastmetricsLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; - /// + /// # use opendal_layer_fastmetrics::FastmetricsLayer; + /// # /// # fn main() -> Result<()> { /// // Pick a builder and configure it. /// let builder = services::Memory::default(); @@ -354,6 +357,7 @@ impl MetricFactory<Histogram> for HistogramFactory { } } +#[doc(hidden)] #[derive(Clone, Debug)] pub struct FastmetricsInterceptor { operation_bytes: Family<OperationLabels, Histogram, HistogramFactory>, @@ -506,7 +510,7 @@ struct OperationLabels { } impl EncodeLabelSet for OperationLabels { - fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> fmt::Result { + fn encode(&self, encoder: &mut dyn LabelSetEncoder) -> std::fmt::Result { encoder.encode(&(observe::LABEL_SCHEME, self.labels.scheme))?; encoder.encode(&(observe::LABEL_NAMESPACE, self.labels.namespace.as_ref()))?; if !self.disable_label_root { diff --git a/core/layers/fastrace/src/lib.rs b/core/layers/fastrace/src/lib.rs index 681425a12..8a3ebd805 100644 --- a/core/layers/fastrace/src/lib.rs +++ b/core/layers/fastrace/src/lib.rs @@ -15,7 +15,11 @@ // specific language governing permissions and limitations // under the License. -use std::fmt::Debug; +//! Fastrace layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::future::Future; use std::sync::Arc; @@ -37,7 +41,7 @@ use opendal_core::*; /// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(FastraceLayer) +/// .layer(FastraceLayer::new()) /// .finish(); /// # Ok(()) /// # } @@ -63,7 +67,7 @@ use opendal_core::*; /// async { /// let _ = dotenvy::dotenv(); /// let op = Operator::new(services::Memory::default())? -/// .layer(FastraceLayer) +/// .layer(FastraceLayer::new()) /// .finish(); /// op.write("test", "0".repeat(16 * 1024 * 1024).into_bytes()) /// .await?; @@ -99,7 +103,16 @@ use opendal_core::*; /// ``` /// /// For real-world usage, please take a look at [`fastrace-datadog`](https://crates.io/crates/fastrace-datadog) or [`fastrace-jaeger`](https://crates.io/crates/fastrace-jaeger) . -pub struct FastraceLayer; +#[derive(Clone, Default)] +#[non_exhaustive] +pub struct FastraceLayer {} + +impl FastraceLayer { + /// Create a new [`FastraceLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for FastraceLayer { type LayeredAccess = FastraceAccessor<A>; @@ -109,6 +122,7 @@ impl<A: Access> Layer<A> for FastraceLayer { } } +#[doc(hidden)] #[derive(Debug)] pub struct FastraceAccessor<A> { inner: A, @@ -208,6 +222,7 @@ impl<A: Access> LayeredAccess for FastraceAccessor<A> { } } +#[doc(hidden)] pub struct FastraceWrapper<R> { span: Span, inner: R, diff --git a/core/layers/hotpath/src/lib.rs b/core/layers/hotpath/src/lib.rs index 6e29b8e2b..85daf53fb 100644 --- a/core/layers/hotpath/src/lib.rs +++ b/core/layers/hotpath/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Hotpath layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::pin::Pin; use std::task::Context; use std::task::Poll; @@ -65,13 +70,22 @@ const LABEL_HTTP_BODY_POLL: &str = "opendal.http.body.poll"; /// # async fn main() -> Result<()> { /// let _guard = hotpath::FunctionsGuardBuilder::new("opendal").build(); /// let op = Operator::new(services::Memory::default())? -/// .layer(HotpathLayer) +/// .layer(HotpathLayer::new()) /// .finish(); /// op.write("test", "hello").await?; /// # Ok(()) /// # } /// ``` -pub struct HotpathLayer; +#[derive(Clone, Default)] +#[non_exhaustive] +pub struct HotpathLayer {} + +impl HotpathLayer { + /// Create a new [`HotpathLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for HotpathLayer { type LayeredAccess = HotpathAccessor<A>; @@ -88,6 +102,7 @@ impl<A: Access> Layer<A> for HotpathLayer { } } +#[doc(hidden)] #[derive(Debug)] pub struct HotpathAccessor<A> { inner: A, @@ -154,6 +169,7 @@ impl<A: Access> LayeredAccess for HotpathAccessor<A> { } } +#[doc(hidden)] pub struct HotpathWrapper<R> { inner: R, } @@ -207,7 +223,7 @@ impl<R: oio::Delete> oio::Delete for HotpathWrapper<R> { } } -pub struct HotpathHttpFetcher { +struct HotpathHttpFetcher { inner: HttpFetcher, } @@ -221,7 +237,7 @@ impl HttpFetch for HotpathHttpFetcher { } } -pub struct HotpathStream<S> { +struct HotpathStream<S> { inner: S, } diff --git a/core/layers/immutable-index/src/lib.rs b/core/layers/immutable-index/src/lib.rs index 82edc5013..aae2df6fe 100644 --- a/core/layers/immutable-index/src/lib.rs +++ b/core/layers/immutable-index/src/lib.rs @@ -15,8 +15,12 @@ // specific language governing permissions and limitations // under the License. +//! Immutable index layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::collections::HashSet; -use std::fmt::Debug; use std::vec::IntoIter; use opendal_core::raw::*; @@ -28,7 +32,7 @@ use opendal_core::*; /// /// # Examples /// -/// ```rust, no_run +/// ```no_run /// # use std::collections::HashMap; /// # /// # use opendal_core::services; @@ -37,7 +41,7 @@ use opendal_core::*; /// # use opendal_layer_immutable_index::ImmutableIndexLayer; /// # /// # fn main() -> Result<()> { -/// let mut iil = ImmutableIndexLayer::default(); +/// let mut iil = ImmutableIndexLayer::new(); /// /// for i in ["file", "dir/", "dir/file", "dir_without_prefix/file"] { /// iil.insert(i.to_string()) @@ -49,11 +53,18 @@ use opendal_core::*; /// # Ok(()) /// # } /// ``` -#[derive(Default, Debug, Clone)] +#[derive(Clone, Default)] pub struct ImmutableIndexLayer { vec: Vec<String>, } +impl ImmutableIndexLayer { + /// Create a new [`ImmutableIndexLayer`]. + pub fn new() -> Self { + Self::default() + } +} + impl ImmutableIndexLayer { /// Insert a key into index. pub fn insert(&mut self, key: String) { @@ -87,7 +98,8 @@ impl<A: Access> Layer<A> for ImmutableIndexLayer { } } -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct ImmutableIndexAccessor<A: Access> { inner: A, vec: Vec<String>, @@ -180,6 +192,7 @@ impl<A: Access> LayeredAccess for ImmutableIndexAccessor<A> { } } +#[doc(hidden)] pub struct ImmutableDir { idx: IntoIter<String>, } diff --git a/core/layers/logging/src/lib.rs b/core/layers/logging/src/lib.rs index 34e112fc1..47c5c2b74 100644 --- a/core/layers/logging/src/lib.rs +++ b/core/layers/logging/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Logging layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; use std::fmt::Display; use std::sync::Arc; @@ -105,7 +110,7 @@ use opendal_core::*; /// # Ok(()) /// # } /// ``` -#[derive(Debug)] +#[derive(Clone)] pub struct LoggingLayer<I = DefaultLoggingInterceptor> { logger: I, } @@ -167,7 +172,7 @@ pub trait LoggingInterceptor: Debug + Clone + Send + Sync + Unpin + 'static { } /// The DefaultLoggingInterceptor will log the message by the standard logging macro. -#[derive(Debug, Copy, Clone, Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct DefaultLoggingInterceptor; impl LoggingInterceptor for DefaultLoggingInterceptor { @@ -229,7 +234,8 @@ impl Display for LoggingContext<'_> { } } -#[derive(Clone, Debug)] +#[doc(hidden)] +#[derive(Debug)] pub struct LoggingAccessor<A: Access, I: LoggingInterceptor> { inner: A, @@ -538,6 +544,7 @@ impl<A: Access, I: LoggingInterceptor> LayeredAccess for LoggingAccessor<A, I> { } } +#[doc(hidden)] pub struct LoggingReader<R, I: LoggingInterceptor> { info: Arc<AccessorInfo>, logger: I, @@ -595,6 +602,7 @@ impl<R: oio::Read, I: LoggingInterceptor> oio::Read for LoggingReader<R, I> { } } +#[doc(hidden)] pub struct LoggingWriter<W, I> { info: Arc<AccessorInfo>, logger: I, @@ -694,6 +702,7 @@ impl<W: oio::Write, I: LoggingInterceptor> oio::Write for LoggingWriter<W, I> { } } +#[doc(hidden)] pub struct LoggingLister<P, I: LoggingInterceptor> { info: Arc<AccessorInfo>, logger: I, @@ -748,6 +757,7 @@ impl<P: oio::List, I: LoggingInterceptor> oio::List for LoggingLister<P, I> { } } +#[doc(hidden)] pub struct LoggingDeleter<D, I: LoggingInterceptor> { info: Arc<AccessorInfo>, logger: I, diff --git a/core/layers/metrics/src/lib.rs b/core/layers/metrics/src/lib.rs index 5c12b7b17..09511cc59 100644 --- a/core/layers/metrics/src/lib.rs +++ b/core/layers/metrics/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Metrics layer (using the [metrics](https://docs.rs/metrics/) crate) implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use metrics::Label; use metrics::counter; use metrics::gauge; @@ -46,7 +51,7 @@ use opendal_layer_observe_metrics_common as observe; /// let _ = Operator::new(services::Memory::default())? /// .layer(MetricsLayer::default()) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` /// @@ -75,9 +80,17 @@ use opendal_layer_observe_metrics_common as observe; /// let (recorder, exporter) = builder.build().expect("failed to build recorder/exporter"); /// let recorder = builder.build_recorder().expect("failed to build recorder"); /// ``` -#[derive(Clone, Debug, Default)] +#[derive(Clone, Default)] +#[non_exhaustive] pub struct MetricsLayer {} +impl MetricsLayer { + /// Create a new [`MetricsLayer`]. + pub fn new() -> Self { + Self::default() + } +} + impl<A: Access> Layer<A> for MetricsLayer { type LayeredAccess = observe::MetricsAccessor<A, MetricsInterceptor>; @@ -87,8 +100,9 @@ impl<A: Access> Layer<A> for MetricsLayer { } } +#[doc(hidden)] #[derive(Clone, Debug)] -pub struct MetricsInterceptor {} +pub struct MetricsInterceptor; impl observe::MetricsIntercept for MetricsInterceptor { fn observe(&self, labels: observe::MetricLabels, value: observe::MetricValue) { diff --git a/core/layers/mime-guess/src/lib.rs b/core/layers/mime-guess/src/lib.rs index 6448a5e81..a7a068b4b 100644 --- a/core/layers/mime-guess/src/lib.rs +++ b/core/layers/mime-guess/src/lib.rs @@ -15,8 +15,13 @@ // specific language governing permissions and limitations // under the License. -use opendal_core::Result; +//! MIME guess layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use opendal_core::raw::*; +use opendal_core::*; /// A layer that can automatically set `Content-Type` based on the file extension in the path. /// @@ -52,15 +57,22 @@ use opendal_core::raw::*; /// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(MimeGuessLayer::default()) +/// .layer(MimeGuessLayer::new()) /// .finish(); /// # Ok(()) /// # } /// ``` -#[derive(Debug, Clone, Default)] +#[derive(Clone, Default)] #[non_exhaustive] pub struct MimeGuessLayer {} +impl MimeGuessLayer { + /// Create a new [`MimeGuessLayer`]. + pub fn new() -> Self { + Self::default() + } +} + impl<A: Access> Layer<A> for MimeGuessLayer { type LayeredAccess = MimeGuessAccessor<A>; @@ -69,7 +81,8 @@ impl<A: Access> Layer<A> for MimeGuessLayer { } } -#[derive(Clone, Debug)] +#[doc(hidden)] +#[derive(Debug)] pub struct MimeGuessAccessor<A: Access>(A); fn mime_from_path(path: &str) -> Option<&str> { @@ -142,9 +155,6 @@ impl<A: Access> LayeredAccess for MimeGuessAccessor<A> { #[cfg(test)] mod tests { use futures::TryStreamExt; - use opendal_core::Metadata; - use opendal_core::Operator; - use opendal_core::services::Memory; use super::*; @@ -153,46 +163,35 @@ mod tests { const HTML: &str = "text/html"; #[tokio::test] - async fn test_async() { - let op = Operator::new(Memory::default()) - .unwrap() - .layer(MimeGuessLayer::default()) + async fn test_async() -> Result<()> { + let op = Operator::new(services::Memory::default())? + .layer(MimeGuessLayer::new()) .finish(); - op.write("test0.html", DATA).await.unwrap(); - assert_eq!( - op.stat("test0.html").await.unwrap().content_type(), - Some(HTML) - ); + op.write("test0.html", DATA).await?; + assert_eq!(op.stat("test0.html").await?.content_type(), Some(HTML)); - op.write("test1.asdfghjkl", DATA).await.unwrap(); - assert_eq!( - op.stat("test1.asdfghjkl").await.unwrap().content_type(), - None - ); + op.write("test1.asdfghjkl", DATA).await?; + assert_eq!(op.stat("test1.asdfghjkl").await?.content_type(), None); op.write_with("test2.html", DATA) .content_type(CUSTOM) - .await - .unwrap(); - assert_eq!( - op.stat("test2.html").await.unwrap().content_type(), - Some(CUSTOM) - ); + .await?; + assert_eq!(op.stat("test2.html").await?.content_type(), Some(CUSTOM)); - let entries: Vec<Metadata> = op + let entries = op .lister_with("") - .await - .unwrap() + .await? .and_then(|entry| { let op = op.clone(); async move { op.stat(entry.path()).await } }) - .try_collect() - .await - .unwrap(); + .try_collect::<Vec<_>>() + .await?; assert_eq!(entries[0].content_type(), Some(HTML)); assert_eq!(entries[1].content_type(), None); assert_eq!(entries[2].content_type(), Some(CUSTOM)); + + Ok(()) } } diff --git a/core/layers/observe-metrics-common/Cargo.toml b/core/layers/observe-metrics-common/Cargo.toml index 2446de6ca..2f7744fb7 100644 --- a/core/layers/observe-metrics-common/Cargo.toml +++ b/core/layers/observe-metrics-common/Cargo.toml @@ -31,9 +31,6 @@ version = { workspace = true } all-features = true [dependencies] -futures = { version = "0.3", default-features = false, features = [ - "std", - "async-await", -] } +futures = { workspace = true } http = { workspace = true } opendal-core = { path = "../../core", version = "0.55.0", default-features = false } diff --git a/core/layers/observe-metrics-common/src/lib.rs b/core/layers/observe-metrics-common/src/lib.rs index d03480204..caf8580eb 100644 --- a/core/layers/observe-metrics-common/src/lib.rs +++ b/core/layers/observe-metrics-common/src/lib.rs @@ -17,7 +17,7 @@ //! OpenDAL Observability //! -//! This module offers essential components to facilitate the implementation of observability in OpenDAL. +//! This library offers essential components to facilitate the implementation of observability in OpenDAL. //! //! # OpenDAL Metrics Reference //! @@ -34,9 +34,9 @@ //! | operation_entries | Histogram | Current operation size in entries, represents the entries being processed | scheme, namespace, root, operation, path | //! | operation_entries_rate | Histogram | Histogram of entries processing rates in entries per second within individual operations | scheme, namespace, root, operation, path | //! | operation_duration_seconds | Histogram | Duration of operations in seconds, measured from start to completion | scheme, namespace, root, operation, path | -//! | operation_errors_total | Counter | Total number of failed operations | scheme, namespace, root, operation, path, error | -//! | operation_executing | Gauge | Number of operations currently being executed | scheme, namespace, root, operation | -//! | operation_ttfb_seconds | Histogram | Time to first byte in seconds for operations | scheme, namespace, root, operation, path | +//! | operation_errors_total | Counter | Total number of failed operations | scheme, namespace, root, operation, path, error | +//! | operation_executing | Gauge | Number of operations currently being executed | scheme, namespace, root, operation | +//! | operation_ttfb_seconds | Histogram | Time to first byte in seconds for operations | scheme, namespace, root, operation, path | //! //! ## HTTP Metrics //! @@ -46,13 +46,13 @@ //! |----------------------------------|-----------|--------------------------------------------------------------------------------------------|-------------------------------------------------| //! | http_connection_errors_total | Counter | Total number of HTTP requests that failed before receiving a response | scheme, namespace, root, operation, error | //! | http_status_errors_total | Counter | Total number of HTTP requests that received error status codes (non-2xx responses) | scheme, namespace, root, operation, status | -//! | http_executing | Gauge | Number of HTTP requests currently in flight from this client | scheme, namespace, root | -//! | http_request_bytes | Histogram | Histogram of HTTP request body sizes in bytes | scheme, namespace, root, operation | -//! | http_request_bytes_rate | Histogram | Histogram of HTTP request bytes per second rates | scheme, namespace, root, operation | +//! | http_executing | Gauge | Number of HTTP requests currently in flight from this client | scheme, namespace, root | +//! | http_request_bytes | Histogram | Histogram of HTTP request body sizes in bytes | scheme, namespace, root, operation | +//! | http_request_bytes_rate | Histogram | Histogram of HTTP request bytes per second rates | scheme, namespace, root, operation | //! | http_request_duration_seconds | Histogram | Histogram of time spent sending HTTP requests, from first byte sent to first byte received | scheme, namespace, root, operation | -//! | http_response_bytes | Histogram | Histogram of HTTP response body sizes in bytes | scheme, namespace, root, operation | -//! | http_response_bytes_rate | Histogram | Histogram of HTTP response bytes per second rates | scheme, namespace, root, operation | -//! | http_response_duration_seconds | Histogram | Histogram of time spent receiving HTTP responses, from first byte to last byte received | scheme, namespace, root, operation | +//! | http_response_bytes | Histogram | Histogram of HTTP response body sizes in bytes | scheme, namespace, root, operation | +//! | http_response_bytes_rate | Histogram | Histogram of HTTP response bytes per second rates | scheme, namespace, root, operation | +//! | http_response_duration_seconds | Histogram | Histogram of time spent receiving HTTP responses, from first byte to last byte received | scheme, namespace, root, operation | //! //! ## Label Descriptions //! @@ -72,6 +72,9 @@ //! * **Counter**: Cumulative metric that only increases over time (resets on restart) //! * **Gauge**: Point-in-time metric that can increase and decrease +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; use std::fmt::Formatter; use std::pin::Pin; @@ -201,7 +204,7 @@ pub static LABEL_ERROR: &str = "error"; pub static LABEL_STATUS_CODE: &str = "status_code"; /// MetricLabels are the labels for the metrics. -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] pub struct MetricLabels { /// The storage scheme identifier (e.g., "s3", "gcs", "azblob", "fs"). /// Used to differentiate between different storage backends. @@ -257,7 +260,7 @@ impl MetricLabels { /// Every metrics impls SHOULD implement observe over the MetricValue to make /// sure they provide the consistent metrics for users. #[non_exhaustive] -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum MetricValue { /// Record the size of data processed in bytes. /// Metrics impl: Update a Histogram with the given byte count. @@ -466,8 +469,7 @@ impl<A: Access, I: MetricsIntercept> Layer<A> for MetricsLayer<I> { } } -/// The metrics http fetcher for opendal. -pub struct MetricsHttpFetcher<I: MetricsIntercept> { +struct MetricsHttpFetcher<I: MetricsIntercept> { inner: HttpFetcher, info: Arc<AccessorInfo>, interceptor: I, @@ -541,7 +543,7 @@ impl<I: MetricsIntercept> HttpFetch for MetricsHttpFetcher<I> { } } -pub struct MetricsStream<S, I> { +struct MetricsStream<S, I> { inner: S, interceptor: I, @@ -591,7 +593,7 @@ where } } -/// The metrics accessor for opendal. +#[doc(hidden)] pub struct MetricsAccessor<A: Access, I: MetricsIntercept> { inner: A, info: Arc<AccessorInfo>, @@ -862,6 +864,7 @@ impl<A: Access, I: MetricsIntercept> LayeredAccess for MetricsAccessor<A, I> { } } +#[doc(hidden)] pub struct MetricsWrapper<R, I: MetricsIntercept> { inner: R, interceptor: I, diff --git a/core/layers/otelmetrics/Cargo.toml b/core/layers/otelmetrics/Cargo.toml index 4a07fbbb8..ca2db89c8 100644 --- a/core/layers/otelmetrics/Cargo.toml +++ b/core/layers/otelmetrics/Cargo.toml @@ -32,7 +32,7 @@ all-features = true [dependencies] opendal-core = { path = "../../core", version = "0.55.0", default-features = false } -opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0", default-features = false } +opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0" } opentelemetry = { version = "0.31.0", default-features = false, features = [ "metrics", ] } diff --git a/core/layers/otelmetrics/src/lib.rs b/core/layers/otelmetrics/src/lib.rs index b52602631..26c5f673e 100644 --- a/core/layers/otelmetrics/src/lib.rs +++ b/core/layers/otelmetrics/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! OpenTelemetry metrics layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use opendal_core::raw::*; use opendal_layer_observe_metrics_common as observe; use opentelemetry::KeyValue; @@ -41,7 +46,7 @@ use opentelemetry::metrics::UpDownCounter; /// # Ok(()) /// # } /// ``` -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct OtelMetricsLayer { interceptor: OtelMetricsInterceptor, } @@ -339,6 +344,7 @@ impl<A: Access> Layer<A> for OtelMetricsLayer { } } +#[doc(hidden)] #[derive(Clone, Debug)] pub struct OtelMetricsInterceptor { operation_bytes: Histogram<u64>, diff --git a/core/layers/oteltrace/src/lib.rs b/core/layers/oteltrace/src/lib.rs index 570a74d2a..170e1f270 100644 --- a/core/layers/oteltrace/src/lib.rs +++ b/core/layers/oteltrace/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! OpenTelemetry trace layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::future::Future; use std::sync::Arc; @@ -43,12 +48,21 @@ use opentelemetry::trace::Tracer; /// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(OtelTraceLayer) +/// .layer(OtelTraceLayer::new()) /// .finish(); /// # Ok(()) /// # } /// ``` -pub struct OtelTraceLayer; +#[derive(Clone, Default)] +#[non_exhaustive] +pub struct OtelTraceLayer {} + +impl OtelTraceLayer { + /// Create a new [`OtelTraceLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for OtelTraceLayer { type LayeredAccess = OtelTraceAccessor<A>; @@ -58,6 +72,7 @@ impl<A: Access> Layer<A> for OtelTraceLayer { } } +#[doc(hidden)] #[derive(Debug)] pub struct OtelTraceAccessor<A> { inner: A, @@ -164,6 +179,7 @@ impl<A: Access> LayeredAccess for OtelTraceAccessor<A> { } } +#[doc(hidden)] pub struct OtelTraceWrapper<R> { _span: BoxedSpan, inner: R, diff --git a/core/layers/prometheus-client/Cargo.toml b/core/layers/prometheus-client/Cargo.toml index e52043a5e..50d7cdf3c 100644 --- a/core/layers/prometheus-client/Cargo.toml +++ b/core/layers/prometheus-client/Cargo.toml @@ -32,7 +32,7 @@ all-features = true [dependencies] opendal-core = { path = "../../core", version = "0.55.0", default-features = false } -opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0", default-features = false } +opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0" } prometheus-client = { version = "0.24" } [dev-dependencies] diff --git a/core/layers/prometheus-client/src/lib.rs b/core/layers/prometheus-client/src/lib.rs index 85f31848b..1b5841d8b 100644 --- a/core/layers/prometheus-client/src/lib.rs +++ b/core/layers/prometheus-client/src/lib.rs @@ -15,10 +15,12 @@ // specific language governing permissions and limitations // under the License. -use std::fmt; +//! Metrics layer (using the [prometheus-client](https://docs.rs/prometheus-client) crate) implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] use opendal_core::raw::*; -use opendal_core::*; use opendal_layer_observe_metrics_common as observe; use prometheus_client::encoding::EncodeLabel; use prometheus_client::encoding::EncodeLabelSet; @@ -43,11 +45,11 @@ use prometheus_client::registry::Unit; /// /// ```no_run /// # use log::info; -/// # use opendal_layer_prometheus_client::PrometheusClientLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_prometheus_client::PrometheusClientLayer; +/// # /// # #[tokio::main] /// # async fn main() -> Result<()> { /// let mut registry = prometheus_client::registry::Registry::default(); @@ -74,7 +76,7 @@ use prometheus_client::registry::Unit; /// # Ok(()) /// # } /// ``` -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct PrometheusClientLayer { interceptor: PrometheusClientInterceptor, } @@ -180,11 +182,11 @@ impl PrometheusClientLayerBuilder { /// # Example /// /// ```no_run - /// # use opendal_layer_prometheus_client::PrometheusClientLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; - /// + /// # use opendal_layer_prometheus_client::PrometheusClientLayer; + /// # /// # #[tokio::main] /// # async fn main() -> Result<()> { /// // Pick a builder and configure it. @@ -378,6 +380,7 @@ impl MetricConstructor<Histogram> for HistogramConstructor { } } +#[doc(hidden)] #[derive(Clone, Debug)] pub struct PrometheusClientInterceptor { operation_bytes: Family<OperationLabels, Histogram, HistogramConstructor>, @@ -488,7 +491,7 @@ struct OperationLabels { } impl EncodeLabelSet for OperationLabels { - fn encode(&self, encoder: &mut LabelSetEncoder<'_>) -> Result<(), fmt::Error> { + fn encode(&self, encoder: &mut LabelSetEncoder<'_>) -> std::fmt::Result { (observe::LABEL_SCHEME, self.labels.scheme).encode(encoder.encode_label())?; (observe::LABEL_NAMESPACE, self.labels.namespace.as_ref()) .encode(encoder.encode_label())?; diff --git a/core/layers/prometheus/Cargo.toml b/core/layers/prometheus/Cargo.toml index 28ff38674..9482fc3bf 100644 --- a/core/layers/prometheus/Cargo.toml +++ b/core/layers/prometheus/Cargo.toml @@ -32,7 +32,7 @@ all-features = true [dependencies] opendal-core = { path = "../../core", version = "0.55.0", default-features = false } -opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0", default-features = false } +opendal-layer-observe-metrics-common = { path = "../observe-metrics-common", version = "0.55.0" } prometheus = { version = "0.14", features = ["process"] } [dev-dependencies] diff --git a/core/layers/prometheus/src/lib.rs b/core/layers/prometheus/src/lib.rs index b1c6fe027..81680c99f 100644 --- a/core/layers/prometheus/src/lib.rs +++ b/core/layers/prometheus/src/lib.rs @@ -15,7 +15,11 @@ // specific language governing permissions and limitations // under the License. -use opendal_core::raw::Access; +//! Metrics layer (using the [prometheus](https://docs.rs/prometheus) crate) implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use opendal_core::raw::*; use opendal_core::*; use opendal_layer_observe_metrics_common as observe; @@ -45,8 +49,8 @@ use prometheus::register_int_gauge_vec_with_registry; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// # use prometheus::Encoder; /// # use opendal_layer_prometheus::PrometheusLayer; +/// # use prometheus::Encoder; /// # /// # #[tokio::main] /// # async fn main() -> Result<()> { @@ -92,13 +96,14 @@ use prometheus::register_int_gauge_vec_with_registry; /// /// ```no_run /// # use std::sync::OnceLock; +/// # /// # use log::info; -/// # use opendal_layer_prometheus::PrometheusLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; +/// # use opendal_layer_prometheus::PrometheusLayer; /// # use prometheus::Encoder; -/// +/// # /// fn global_prometheus_layer() -> &'static PrometheusLayer { /// static GLOBAL: OnceLock<PrometheusLayer> = OnceLock::new(); /// GLOBAL.get_or_init(|| { @@ -134,7 +139,7 @@ use prometheus::register_int_gauge_vec_with_registry; /// # Ok(()) /// # } /// ``` -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct PrometheusLayer { interceptor: PrometheusInterceptor, } @@ -145,10 +150,10 @@ impl PrometheusLayer { /// # Example /// /// ```no_run - /// # use opendal_layer_prometheus::PrometheusLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; + /// # use opendal_layer_prometheus::PrometheusLayer; /// # /// # #[tokio::main] /// # async fn main() -> Result<()> { @@ -260,10 +265,10 @@ impl PrometheusLayerBuilder { /// # Example /// /// ```no_run - /// # use opendal_layer_prometheus::PrometheusLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; + /// # use opendal_layer_prometheus::PrometheusLayer; /// # /// # #[tokio::main] /// # async fn main() -> Result<()> { @@ -498,10 +503,10 @@ impl PrometheusLayerBuilder { /// # Example /// /// ```no_run - /// # use opendal_layer_prometheus::PrometheusLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; + /// # use opendal_layer_prometheus::PrometheusLayer; /// # /// # #[tokio::main] /// # async fn main() -> Result<()> { @@ -528,6 +533,7 @@ fn parse_prometheus_error(err: prometheus::Error) -> Error { Error::new(ErrorKind::Unexpected, err.to_string()).set_source(err) } +#[doc(hidden)] #[derive(Clone, Debug)] pub struct PrometheusInterceptor { operation_bytes: HistogramVec, diff --git a/core/layers/retry/Cargo.toml b/core/layers/retry/Cargo.toml index 03c0a0b34..dffaafade 100644 --- a/core/layers/retry/Cargo.toml +++ b/core/layers/retry/Cargo.toml @@ -37,10 +37,10 @@ opendal-core = { path = "../../core", version = "0.55.0", default-features = fal [dev-dependencies] bytes = { workspace = true } -futures = { workspace = true, default-features = true } +futures = { workspace = true } opendal-core = { path = "../../core", version = "0.55.0" } -opendal-layer-logging = { path = "../logging", version = "0.55.0", default-features = false } -opendal-layer-timeout = { path = "../timeout", version = "0.55.0", default-features = false } +opendal-layer-logging = { path = "../logging", version = "0.55.0" } +opendal-layer-timeout = { path = "../timeout", version = "0.55.0" } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } tracing-subscriber = { version = "0.3", features = [ "env-filter", diff --git a/core/layers/retry/src/lib.rs b/core/layers/retry/src/lib.rs index 1ba9e5864..4ffeafc2f 100644 --- a/core/layers/retry/src/lib.rs +++ b/core/layers/retry/src/lib.rs @@ -15,8 +15,12 @@ // specific language governing permissions and limitations // under the License. +//! Retry layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; -use std::fmt::Formatter; use std::sync::Arc; use backon::ExponentialBuilder; @@ -56,10 +60,10 @@ use opendal_core::*; /// # fn main() -> Result<()> { /// let op = Operator::new(services::Memory::default())? /// // This is fine, since timeout happen during retry. -/// .layer(TimeoutLayer::new().with_io_timeout(Duration::from_nanos(1))) -/// .layer(RetryLayer::new()) +/// .layer(TimeoutLayer::default().with_io_timeout(Duration::from_nanos(1))) +/// .layer(RetryLayer::default()) /// // This is wrong. Since timeout layer will drop future, leaving retry layer in a bad state. -/// .layer(TimeoutLayer::new().with_io_timeout(Duration::from_nanos(1))) +/// .layer(TimeoutLayer::default().with_io_timeout(Duration::from_nanos(1))) /// .finish(); /// # Ok(()) /// # } @@ -75,7 +79,7 @@ use opendal_core::*; /// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(RetryLayer::new()) +/// .layer(RetryLayer::default()) /// .finish(); /// # Ok(()) /// # } @@ -106,7 +110,7 @@ use opendal_core::*; /// /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(RetryLayer::new().with_notify(MyRetryInterceptor)) +/// .layer(RetryLayer::default().with_notify(MyRetryInterceptor)) /// .finish(); /// # Ok(()) /// # } @@ -135,18 +139,7 @@ impl Default for RetryLayer { } impl RetryLayer { - /// Create a new retry layer. - /// # Examples - /// - /// ```no_run - /// use opendal_core::services; - /// use opendal_core::Operator; - /// use opendal_layer_retry::RetryLayer; - /// - /// let _ = Operator::new(services::Memory::default()) - /// .expect("must init") - /// .layer(RetryLayer::new()); - /// ``` + /// Create a new [`RetryLayer`]. pub fn new() -> RetryLayer { Self::default() } @@ -164,7 +157,7 @@ impl<I: RetryInterceptor> RetryLayer<I> { /// /// let _ = Operator::new(services::Memory::default()) /// .expect("must init") - /// .layer(RetryLayer::new().with_notify(notify)) + /// .layer(RetryLayer::default().with_notify(notify)) /// .finish(); /// ``` pub fn with_notify<NI: RetryInterceptor>(self, notify: NI) -> RetryLayer<NI> { @@ -269,6 +262,7 @@ impl RetryInterceptor for DefaultRetryInterceptor { } } +#[doc(hidden)] pub struct RetryAccessor<A: Access, I: RetryInterceptor> { inner: Arc<A>, builder: ExponentialBuilder, @@ -276,7 +270,7 @@ pub struct RetryAccessor<A: Access, I: RetryInterceptor> { } impl<A: Access, I: RetryInterceptor> Debug for RetryAccessor<A, I> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("RetryAccessor") .field("inner", &self.inner) .finish_non_exhaustive() @@ -375,6 +369,7 @@ impl<A: Access, I: RetryInterceptor> LayeredAccess for RetryAccessor<A, I> { } } +#[doc(hidden)] pub struct RetryReader<A, R> { inner: Arc<A>, reader: Option<R>, @@ -415,6 +410,7 @@ impl<A: Access> oio::Read for RetryReader<A, A::Reader> { } } +#[doc(hidden)] pub struct RetryWrapper<R, I> { inner: Option<R>, notify: Arc<I>, @@ -840,20 +836,19 @@ mod tests { } #[tokio::test] - async fn test_retry_read() { + async fn test_retry_read() -> Result<()> { let _ = tracing_subscriber::fmt() .with_max_level(LevelFilter::TRACE) .with_test_writer() .try_init(); let builder = MockBuilder::default(); - let op = Operator::new(builder.clone()) - .unwrap() + let op = Operator::new(builder.clone())? .layer(LoggingLayer::default()) - .layer(RetryLayer::new()) + .layer(RetryLayer::default()) .finish(); - let r = op.reader("retryable_error").await.unwrap(); + let r = op.reader("retryable_error").await?; let mut content = Vec::new(); let size = r .read_into(&mut content, ..) @@ -863,49 +858,49 @@ mod tests { assert_eq!(content, "Hello, World!".as_bytes()); // The error is retryable, we should request it 3 times. assert_eq!(*builder.attempt.lock().unwrap(), 5); + Ok(()) } /// This test is used to reproduce the panic issue while composing retry layer with timeout layer. #[tokio::test] - async fn test_retry_write_fail_on_close() { + async fn test_retry_write_fail_on_close() -> Result<()> { let _ = tracing_subscriber::fmt() .with_max_level(LevelFilter::TRACE) .with_test_writer() .try_init(); let builder = MockBuilder::default(); - let op = Operator::new(builder.clone()) - .unwrap() + let op = Operator::new(builder.clone())? .layer( - RetryLayer::new() + RetryLayer::default() .with_min_delay(Duration::from_millis(1)) .with_max_delay(Duration::from_millis(1)) .with_jitter(), ) // Uncomment this to reproduce timeout layer panic. - // .layer(TimeoutLayer::new().with_io_timeout(Duration::from_nanos(1))) + // .layer(TimeoutLayer::default().with_io_timeout(Duration::from_nanos(1))) .layer(LoggingLayer::default()) .finish(); - let mut w = op.writer("test_write").await.unwrap(); - w.write("aaa").await.unwrap(); - w.write("bbb").await.unwrap(); + let mut w = op.writer("test_write").await?; + w.write("aaa").await?; + w.write("bbb").await?; match w.close().await { Ok(_) => (), Err(_) => { - w.abort().await.unwrap(); + w.abort().await?; } }; + Ok(()) } #[tokio::test] - async fn test_retry_list() { + async fn test_retry_list() -> Result<()> { let _ = tracing_subscriber::fmt().with_test_writer().try_init(); let builder = MockBuilder::default(); - let op = Operator::new(builder.clone()) - .unwrap() - .layer(RetryLayer::new()) + let op = Operator::new(builder.clone())? + .layer(RetryLayer::default()) .finish(); let expected = vec!["hello", "world", "2023/", "0208/"]; @@ -920,25 +915,26 @@ mod tests { } assert_eq!(actual, expected); + Ok(()) } #[tokio::test] - async fn test_retry_batch() { + async fn test_retry_batch() -> Result<()> { let _ = tracing_subscriber::fmt().with_test_writer().try_init(); let builder = MockBuilder::default(); // set to a lower delay to make it run faster - let op = Operator::new(builder.clone()) - .unwrap() + let op = Operator::new(builder.clone())? .layer( - RetryLayer::new() + RetryLayer::default() .with_min_delay(Duration::from_secs_f32(0.1)) .with_max_times(5), ) .finish(); let paths = vec!["hello", "world", "test", "batch"]; - op.delete_stream(stream::iter(paths)).await.unwrap(); + op.delete_stream(stream::iter(paths)).await?; assert_eq!(*builder.attempt.lock().unwrap(), 5); + Ok(()) } } diff --git a/core/layers/tail-cut/src/lib.rs b/core/layers/tail-cut/src/lib.rs index 3ecaedbaa..fd473ac3b 100644 --- a/core/layers/tail-cut/src/lib.rs +++ b/core/layers/tail-cut/src/lib.rs @@ -15,8 +15,12 @@ // specific language governing permissions and limitations // under the License. +//! Tail cut layer (that automatically cancels long-tail requests) implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; -use std::fmt::Formatter; use std::sync::Arc; use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; @@ -74,7 +78,7 @@ impl Default for TailCutLayerBuilder { } impl TailCutLayerBuilder { - /// Create a new builder with default settings. + /// Create a new [`TailCutLayerBuilder`] with default settings. pub fn new() -> Self { Self::default() } @@ -263,23 +267,23 @@ pub struct TailCutLayer { stats: Arc<TailCutStats>, } +impl Default for TailCutLayer { + fn default() -> Self { + Self::builder().build() + } +} + impl TailCutLayer { - /// Create a builder to configure the layer. + /// Create a new [`TailCutLayerBuilder`] to configure the layer. pub fn builder() -> TailCutLayerBuilder { - TailCutLayerBuilder::new() + TailCutLayerBuilder::default() } - /// Create a layer with default settings. + /// Create a new [`TailCutLayer`]. /// /// This is equivalent to `TailCutLayer::builder().build()`. pub fn new() -> Self { - Self::builder().build() - } -} - -impl Default for TailCutLayer { - fn default() -> Self { - Self::new() + Self::default() } } @@ -295,8 +299,7 @@ impl<A: Access> Layer<A> for TailCutLayer { } } -/// Accessor that implements tail cut logic. -#[derive(Clone)] +#[doc(hidden)] pub struct TailCutAccessor<A: Access> { inner: A, config: Arc<TailCutConfig>, @@ -304,7 +307,7 @@ pub struct TailCutAccessor<A: Access> { } impl<A: Access> Debug for TailCutAccessor<A> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("TailCutAccessor") .field("config", &self.config) .finish_non_exhaustive() @@ -441,7 +444,7 @@ impl<A: Access> LayeredAccess for TailCutAccessor<A> { } } -/// Wrapper for IO operations (Reader, Writer, Lister, Deleter). +#[doc(hidden)] pub struct TailCutWrapper<R> { inner: R, size: Option<u64>, diff --git a/core/layers/throttle/Cargo.toml b/core/layers/throttle/Cargo.toml index 89e322184..03e72dc7b 100644 --- a/core/layers/throttle/Cargo.toml +++ b/core/layers/throttle/Cargo.toml @@ -31,7 +31,7 @@ version = { workspace = true } all-features = true [dependencies] -governor = { version = "0.10.1", features = ["std"] } +governor = "0.10.1" opendal-core = { path = "../../core", version = "0.55.0", default-features = false } [dev-dependencies] diff --git a/core/layers/throttle/src/lib.rs b/core/layers/throttle/src/lib.rs index 2127855f7..3e8d7b644 100644 --- a/core/layers/throttle/src/lib.rs +++ b/core/layers/throttle/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Throttle layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::num::NonZeroU32; use std::sync::Arc; @@ -24,7 +29,6 @@ use governor::clock::DefaultClock; use governor::middleware::NoOpMiddleware; use governor::state::InMemoryState; use governor::state::NotKeyed; - use opendal_core::raw::*; use opendal_core::*; @@ -49,17 +53,17 @@ use opendal_core::*; /// This example limits bandwidth to 10 KiB/s and burst size to 10 MiB. /// /// ```no_run -/// # use opendal_layer_throttle::ThrottleLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_throttle::ThrottleLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default()) /// .expect("must init") /// .layer(ThrottleLayer::new(10 * 1024, 10000 * 1024)) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` #[derive(Clone)] @@ -86,12 +90,12 @@ impl ThrottleLayer { impl<A: Access> Layer<A> for ThrottleLayer { type LayeredAccess = ThrottleAccessor<A>; - fn layer(&self, accessor: A) -> Self::LayeredAccess { + fn layer(&self, inner: A) -> Self::LayeredAccess { let rate_limiter = Arc::new(RateLimiter::direct( Quota::per_second(self.bandwidth).allow_burst(self.burst), )); ThrottleAccessor { - inner: accessor, + inner, rate_limiter, } } @@ -102,7 +106,8 @@ impl<A: Access> Layer<A> for ThrottleLayer { /// Read more about [Middleware](https://docs.rs/governor/latest/governor/middleware/index.html) type SharedRateLimiter = Arc<RateLimiter<NotKeyed, InMemoryState, DefaultClock, NoOpMiddleware>>; -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct ThrottleAccessor<A: Access> { inner: A, rate_limiter: SharedRateLimiter, @@ -146,13 +151,14 @@ impl<A: Access> LayeredAccess for ThrottleAccessor<A> { } } +#[doc(hidden)] pub struct ThrottleWrapper<R> { inner: R, limiter: SharedRateLimiter, } impl<R> ThrottleWrapper<R> { - pub fn new(inner: R, rate_limiter: SharedRateLimiter) -> Self { + fn new(inner: R, rate_limiter: SharedRateLimiter) -> Self { Self { inner, limiter: rate_limiter, diff --git a/core/layers/timeout/Cargo.toml b/core/layers/timeout/Cargo.toml index 20099fb22..ae581e9e8 100644 --- a/core/layers/timeout/Cargo.toml +++ b/core/layers/timeout/Cargo.toml @@ -37,5 +37,5 @@ tokio = { workspace = true, features = ["time"] } [dev-dependencies] futures = { workspace = true } opendal-core = { path = "../../core", version = "0.55.0" } -opendal-layer-retry = { path = "../retry", version = "0.55.0", default-features = false } +opendal-layer-retry = { path = "../retry", version = "0.55.0" } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/core/layers/timeout/src/lib.rs b/core/layers/timeout/src/lib.rs index dc6c881c3..2cd56bf70 100644 --- a/core/layers/timeout/src/lib.rs +++ b/core/layers/timeout/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Timeout layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::future::Future; use std::sync::Arc; use std::time::Duration; @@ -63,10 +68,10 @@ use opendal_core::*; /// # fn main() -> Result<()> { /// let op = Operator::new(services::Memory::default())? /// // This is fine, since timeout happen during retry. -/// .layer(TimeoutLayer::new().with_io_timeout(Duration::from_nanos(1))) -/// .layer(RetryLayer::new()) +/// .layer(TimeoutLayer::default().with_io_timeout(Duration::from_nanos(1))) +/// .layer(RetryLayer::default()) /// // This is wrong. Since timeout layer will drop future, leaving retry layer in a bad state. -/// .layer(TimeoutLayer::new().with_io_timeout(Duration::from_nanos(1))) +/// .layer(TimeoutLayer::default().with_io_timeout(Duration::from_nanos(1))) /// .finish(); /// # Ok(()) /// # } @@ -127,7 +132,7 @@ impl Default for TimeoutLayer { } impl TimeoutLayer { - /// Create a new `TimeoutLayer` with default settings. + /// Create a new [`TimeoutLayer`] with default settings. pub fn new() -> Self { Self::default() } @@ -167,7 +172,8 @@ impl<A: Access> Layer<A> for TimeoutLayer { } } -#[derive(Debug, Clone)] +#[doc(hidden)] +#[derive(Debug)] pub struct TimeoutAccessor<A: Access> { inner: A, @@ -262,13 +268,13 @@ impl<A: Access> LayeredAccess for TimeoutAccessor<A> { } } -pub struct TimeoutExecutor { +struct TimeoutExecutor { exec: Arc<dyn Execute>, timeout: Duration, } impl TimeoutExecutor { - pub fn new(exec: Arc<dyn Execute>, timeout: Duration) -> Self { + fn new(exec: Arc<dyn Execute>, timeout: Duration) -> Self { Self { exec, timeout } } } @@ -283,6 +289,7 @@ impl Execute for TimeoutExecutor { } } +#[doc(hidden)] pub struct TimeoutWrapper<R> { inner: R, @@ -353,12 +360,9 @@ impl<R: oio::Delete> oio::Delete for TimeoutWrapper<R> { #[cfg(test)] mod tests { - use std::future::Future; use std::future::pending; use futures::StreamExt; - use opendal_core::raw::*; - use opendal_core::*; use tokio::time::sleep; use tokio::time::timeout; @@ -423,7 +427,7 @@ mod tests { async fn test_operation_timeout() { let srv = MockService; let op = Operator::from_inner(Arc::new(srv)) - .layer(TimeoutLayer::new().with_timeout(Duration::from_secs(1))); + .layer(TimeoutLayer::default().with_timeout(Duration::from_secs(1))); let fut = async { let res = op.delete("test").await; @@ -442,7 +446,7 @@ mod tests { async fn test_io_timeout() { let srv = MockService; let op = Operator::from_inner(Arc::new(srv)) - .layer(TimeoutLayer::new().with_io_timeout(Duration::from_secs(1))); + .layer(TimeoutLayer::default().with_io_timeout(Duration::from_secs(1))); let reader = op.reader("test").await.unwrap(); @@ -457,7 +461,7 @@ mod tests { async fn test_list_timeout() { let srv = MockService; let op = Operator::from_inner(Arc::new(srv)).layer( - TimeoutLayer::new() + TimeoutLayer::default() .with_timeout(Duration::from_secs(1)) .with_io_timeout(Duration::from_secs(1)), ); @@ -476,7 +480,7 @@ mod tests { use oio::List; let acc = MockService; - let timeout_layer = TimeoutLayer::new() + let timeout_layer = TimeoutLayer::default() .with_timeout(Duration::from_secs(1)) .with_io_timeout(Duration::from_secs(1)); let timeout_acc = timeout_layer.layer(acc); diff --git a/core/layers/tracing/src/lib.rs b/core/layers/tracing/src/lib.rs index e7fadf54f..01139944d 100644 --- a/core/layers/tracing/src/lib.rs +++ b/core/layers/tracing/src/lib.rs @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +//! Tracing layer implementation for Apache OpenDAL. + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(missing_docs)] + use std::fmt::Debug; use std::pin::Pin; use std::task::Context; @@ -22,13 +27,12 @@ use std::task::Poll; use futures::Stream; use futures::StreamExt; +use opendal_core::raw::*; +use opendal_core::*; use tracing::Level; use tracing::Span; use tracing::span; -use opendal_core::raw::*; -use opendal_core::*; - /// Add [tracing](https://docs.rs/tracing/) for every operation. /// /// # Examples @@ -36,16 +40,16 @@ use opendal_core::*; /// ## Basic Setup /// /// ```no_run -/// # use opendal_layer_tracing::TracingLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; /// # use opendal_core::Result; -/// +/// # use opendal_layer_tracing::TracingLayer; +/// # /// # fn main() -> Result<()> { /// let _ = Operator::new(services::Memory::default())? -/// .layer(TracingLayer) +/// .layer(TracingLayer::new()) /// .finish(); -/// Ok(()) +/// # Ok(()) /// # } /// ``` /// @@ -53,15 +57,15 @@ use opendal_core::*; /// /// ```no_run /// # use anyhow::Result; -/// # use opendal_layer_tracing::TracingLayer; /// # use opendal_core::services; /// # use opendal_core::Operator; +/// # use opendal_layer_tracing::TracingLayer; /// # use opentelemetry::KeyValue; /// # use opentelemetry_sdk::trace; /// # use opentelemetry_sdk::Resource; /// # use tracing_subscriber::prelude::*; /// # use tracing_subscriber::EnvFilter; -/// +/// # /// # fn main() -> Result<()> { /// use opentelemetry::trace::TracerProvider; /// let tracer_provider = opentelemetry_sdk::trace::SdkTracerProvider::builder() @@ -92,7 +96,7 @@ use opendal_core::*; /// /// let _ = dotenvy::dotenv(); /// let op = Operator::new(services::Memory::default())? -/// .layer(TracingLayer) +/// .layer(TracingLayer::new()) /// .finish(); /// /// op.write("test", "0".repeat(16 * 1024 * 1024).into_bytes()) @@ -107,8 +111,7 @@ use opendal_core::*; /// // This will invoke the shutdown method on all span processors. /// // span processors should export remaining spans before return. /// tracer_provider.shutdown()?; -/// -/// Ok(()) +/// # Ok(()) /// # } /// ``` /// @@ -128,7 +131,7 @@ use opendal_core::*; /// # use tracing::span::Id; /// # use tracing::span::Record; /// # use tracing::subscriber::Subscriber; -/// +/// # /// # pub struct FooSubscriber; /// # impl Subscriber for FooSubscriber { /// # fn enabled(&self, _: &Metadata) -> bool { false } @@ -146,7 +149,16 @@ use opendal_core::*; /// ``` /// /// For real-world usage, please take a look at [`tracing-opentelemetry`](https://crates.io/crates/tracing-opentelemetry). -pub struct TracingLayer; +#[derive(Clone, Default)] +#[non_exhaustive] +pub struct TracingLayer {} + +impl TracingLayer { + /// Create a new [`TracingLayer`]. + pub fn new() -> Self { + Self::default() + } +} impl<A: Access> Layer<A> for TracingLayer { type LayeredAccess = TracingAccessor<A>; @@ -165,7 +177,7 @@ impl<A: Access> Layer<A> for TracingLayer { } } -pub struct TracingHttpFetcher { +struct TracingHttpFetcher { inner: HttpFetcher, } @@ -184,7 +196,7 @@ impl HttpFetch for TracingHttpFetcher { } } -pub struct TracingStream<S> { +struct TracingStream<S> { inner: S, span: Span, } @@ -201,6 +213,7 @@ where } } +#[doc(hidden)] #[derive(Debug)] pub struct TracingAccessor<A> { inner: A, @@ -287,6 +300,7 @@ impl<A: Access> LayeredAccess for TracingAccessor<A> { } } +#[doc(hidden)] pub struct TracingWrapper<R> { span: Span, inner: R,
