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 18fa9fe95 chore(layers): unify layer crates and gate dtrace on linux
(#7094)
18fa9fe95 is described below
commit 18fa9fe953f8579c9c4685a00d2524a68dad7bbb
Author: Qinxuan Chen <[email protected]>
AuthorDate: Sun Dec 28 11:45:19 2025 +0800
chore(layers): unify layer crates and gate dtrace on linux (#7094)
* 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
* fix toml fmt
* update docs
---
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 | 43 ++++++++----
core/layers/fastmetrics/src/lib.rs | 12 +++-
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 +++++++-----
35 files changed, 471 insertions(+), 289 deletions(-)
diff --git a/core/Cargo.lock b/core/Cargo.lock
index ff85dd83b..e3052f5e8 100644
--- a/core/Cargo.lock
+++ b/core/Cargo.lock
@@ -5783,6 +5783,7 @@ dependencies = [
"bytes",
"opendal-core",
"probe",
+ "tokio",
]
[[package]]
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 013261659..9ae0a8afe 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -208,7 +208,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 }
@@ -288,6 +287,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..c65ccb3a8 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..0d288dc21 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,17 @@ 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 {
+ /// Create a new [`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 +144,7 @@ impl<A: Access> Layer<A> for DtraceLayer {
}
}
-#[derive(Clone)]
+#[doc(hidden)]
pub struct DTraceAccessor<A: Access> {
inner: A,
}
@@ -218,13 +230,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/src/lib.rs
b/core/layers/fastmetrics/src/lib.rs
index cb9a044f5..3bde49b1f 100644
--- a/core/layers/fastmetrics/src/lib.rs
+++ b/core/layers/fastmetrics/src/lib.rs
@@ -15,6 +15,11 @@
// specific language governing permissions and limitations
// under the License.
+//! 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;
use fastmetrics::metrics::counter::Counter;
@@ -122,7 +127,7 @@ use opendal_layer_observe_metrics_common as observe;
/// println!("{}", output);
/// # Ok(())
/// # }
-#[derive(Clone, Debug)]
+#[derive(Clone)]
pub struct FastmetricsLayer {
interceptor: FastmetricsInterceptor,
}
@@ -322,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();
@@ -352,6 +357,7 @@ impl MetricFactory<Histogram> for HistogramFactory {
}
}
+#[doc(hidden)]
#[derive(Clone, Debug)]
pub struct FastmetricsInterceptor {
operation_bytes: Family<OperationLabels, Histogram, HistogramFactory>,
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,