This is an automated email from the ASF dual-hosted git repository. tison pushed a commit to branch opt-out-ctor in repository https://gitbox.apache.org/repos/asf/opendal.git
commit 7472c19b9d4c1ae28b26626dc5eb3cbf75738375 Author: tison <[email protected]> AuthorDate: Wed Feb 18 21:56:34 2026 +0800 refactor(core): allow opt-out ctor dependency Signed-off-by: tison <[email protected]> --- core/Cargo.toml | 4 ++- 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, 29 insertions(+), 35 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index f1a19d950..1cc1e1bd4 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -117,6 +117,8 @@ layers-tail-cut = ["dep:opendal-layer-tail-cut"] layers-throttle = ["dep:opendal-layer-throttle"] layers-timeout = ["dep:opendal-layer-timeout"] layers-tracing = ["dep:opendal-layer-tracing"] +# Register services enabled to the OperatorRegistry so that they can be used by `Operator::from_uri`. +register-services = ["dep:ctor"] reqwest-rustls-tls = ["opendal-core/reqwest-rustls-tls"] services-aliyun-drive = ["dep:opendal-service-aliyun-drive"] services-alluxio = ["dep:opendal-service-alluxio"] @@ -207,7 +209,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..6a58d0def 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 = "register-services")] #[ctor::ctor] fn register_default_operator_registry() { init_default_registry();
