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 b9a78ac33 refactor(core): allow opt-out ctor dependency (#7196)
b9a78ac33 is described below
commit b9a78ac3304d0872b089eb6621466035951ec1c2
Author: tison <[email protected]>
AuthorDate: Sun Feb 22 13:47:19 2026 +0800
refactor(core): allow opt-out ctor dependency (#7196)
* refactor(core): allow opt-out ctor dependency
Signed-off-by: tison <[email protected]>
* fixup
Signed-off-by: tison <[email protected]>
* rename feature
Signed-off-by: tison <[email protected]>
---------
Signed-off-by: tison <[email protected]>
---
core/Cargo.toml | 5 +++-
core/core/src/types/mod.rs | 1 -
core/core/src/types/operator/builder.rs | 2 +-
core/core/src/types/operator/mod.rs | 2 +-
core/core/src/types/operator/registry.rs | 42 +++++++++++++++-----------------
core/src/lib.rs | 13 ++++------
6 files changed, 30 insertions(+), 35 deletions(-)
diff --git a/core/Cargo.toml b/core/Cargo.toml
index f1a19d950..93be3579f 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -81,8 +81,11 @@ unused_async = "warn"
all-features = true
[features]
+# Register services enabled to the OperatorRegistry so that they can be used
by `Operator::from_uri`.
+auto-register-services = ["dep:ctor"]
blocking = ["opendal-core/blocking"]
default = [
+ "auto-register-services",
"reqwest-rustls-tls",
"executors-tokio",
"layers-concurrent-limit",
@@ -207,7 +210,7 @@ path = "tests/behavior/main.rs"
required-features = ["tests"]
[dependencies]
-ctor = { workspace = true }
+ctor = { workspace = true, optional = true }
opendal-core = { path = "core", version = "0.55.0", default-features = false }
opendal-layer-async-backtrace = { path = "layers/async-backtrace", version =
"0.55.0", optional = true, default-features = false }
opendal-layer-await-tree = { path = "layers/await-tree", version = "0.55.0",
optional = true, default-features = false }
diff --git a/core/core/src/types/mod.rs b/core/core/src/types/mod.rs
index fb168553f..8042804ae 100644
--- a/core/core/src/types/mod.rs
+++ b/core/core/src/types/mod.rs
@@ -43,7 +43,6 @@ mod execute;
pub use execute::*;
mod operator;
-pub use operator::DEFAULT_OPERATOR_REGISTRY;
pub use operator::IntoOperatorUri;
pub use operator::Operator;
pub use operator::OperatorBuilder;
diff --git a/core/core/src/types/operator/builder.rs
b/core/core/src/types/operator/builder.rs
index 195006a8b..201f87612 100644
--- a/core/core/src/types/operator/builder.rs
+++ b/core/core/src/types/operator/builder.rs
@@ -142,7 +142,7 @@ impl Operator {
/// # }
/// ```
pub fn from_uri(uri: impl IntoOperatorUri) -> Result<Operator> {
- crate::DEFAULT_OPERATOR_REGISTRY.load(uri)
+ OperatorRegistry::get().load(uri)
}
/// Create a new operator via given scheme and iterator of config value in
dynamic dispatch.
diff --git a/core/core/src/types/operator/mod.rs
b/core/core/src/types/operator/mod.rs
index 3de1ea7c1..7dba388e5 100644
--- a/core/core/src/types/operator/mod.rs
+++ b/core/core/src/types/operator/mod.rs
@@ -30,7 +30,7 @@ pub use info::OperatorInfo;
pub mod operator_futures;
mod registry;
-pub use registry::{DEFAULT_OPERATOR_REGISTRY, OperatorFactory,
OperatorRegistry};
+pub use registry::{OperatorFactory, OperatorRegistry};
mod uri;
pub use uri::{IntoOperatorUri, OperatorUri};
diff --git a/core/core/src/types/operator/registry.rs
b/core/core/src/types/operator/registry.rs
index dc10beb5e..d95a681ec 100644
--- a/core/core/src/types/operator/registry.rs
+++ b/core/core/src/types/operator/registry.rs
@@ -15,42 +15,38 @@
// specific language governing permissions and limitations
// under the License.
-use std::collections::HashMap;
-use std::sync::{LazyLock, Mutex};
-
use crate::types::builder::{Builder, Configurator};
use crate::types::{IntoOperatorUri, OperatorUri};
use crate::{Error, ErrorKind, Operator, Result};
+use std::collections::HashMap;
+use std::sync::{LazyLock, Mutex};
/// Factory signature used to construct [`Operator`] from a URI and extra
options.
pub type OperatorFactory = fn(&OperatorUri) -> Result<Operator>;
-/// Default registry used by [`Operator::from_uri`].
-///
-/// `memory` is always registered here since it's used pervasively in unit
tests
-/// and as a zero-dependency backend.
-///
-/// Other optional service registrations are handled by the facade crate
`opendal`.
-pub static DEFAULT_OPERATOR_REGISTRY: LazyLock<OperatorRegistry> =
LazyLock::new(|| {
- let registry = OperatorRegistry::new();
-
- crate::services::register_memory_service(®istry);
-
- registry
-});
-
/// Global registry that maps schemes to [`OperatorFactory`] functions.
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct OperatorRegistry {
factories: Mutex<HashMap<String, OperatorFactory>>,
}
impl OperatorRegistry {
- /// Create a new, empty registry.
- pub fn new() -> Self {
- Self {
- factories: Mutex::new(HashMap::new()),
- }
+ /// Get the global registry.
+ pub fn get() -> &'static Self {
+ /// The global registry used by [`Operator::from_uri`].
+ ///
+ /// `memory` is always registered here since it's used pervasively in
unit tests
+ /// and as a zero-dependency backend.
+ ///
+ /// Other optional service registrations are handled by the facade
crate `opendal`.
+ static OPERATOR_REGISTRY: LazyLock<OperatorRegistry> =
LazyLock::new(|| {
+ let factories = Mutex::new(HashMap::default());
+ let registry = OperatorRegistry { factories };
+ crate::services::register_memory_service(®istry);
+ registry
+ });
+
+ &OPERATOR_REGISTRY
}
/// Register a builder for the given scheme.
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 5563bd712..f3e7a3bc2 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -27,9 +27,7 @@ pub use opendal_core::*;
#[cfg(feature = "tests")]
pub extern crate opendal_testkit as tests;
-static DEFAULT_REGISTRY_INIT: std::sync::Once = std::sync::Once::new();
-
-/// Initialize [`DEFAULT_OPERATOR_REGISTRY`] with enabled services.
+/// Initialize the global [`OperatorRegistry`] with enabled services.
///
/// This function is safe to call multiple times and will only perform
/// initialization once.
@@ -41,13 +39,11 @@ static DEFAULT_REGISTRY_INIT: std::sync::Once =
std::sync::Once::new();
/// should call this function explicitly before using `Operator::from_uri` or
/// `Operator::via_iter`.
pub fn init_default_registry() {
- DEFAULT_REGISTRY_INIT.call_once(|| {
- let registry = &opendal_core::DEFAULT_OPERATOR_REGISTRY;
- init_default_registry_inner(registry);
- });
+ static DEFAULT_REGISTRY_INIT: std::sync::Once = std::sync::Once::new();
+ DEFAULT_REGISTRY_INIT.call_once(||
init_default_registry_inner(OperatorRegistry::get()));
}
-fn init_default_registry_inner(registry: &opendal_core::OperatorRegistry) {
+fn init_default_registry_inner(registry: &OperatorRegistry) {
opendal_core::services::register_memory_service(registry);
#[cfg(feature = "services-aliyun-drive")]
@@ -234,6 +230,7 @@ fn init_default_registry_inner(registry:
&opendal_core::OperatorRegistry) {
opendal_service_redis::register_redis_service(registry);
}
+#[cfg(feature = "auto-register-services")]
#[ctor::ctor]
fn register_default_operator_registry() {
init_default_registry();