From d26d98104a80b4518b405bafb623ed0b45ddad07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Sun, 21 Jun 2026 09:52:19 +0800 Subject: [PATCH] refactor: prune ecstore root global facades (#3680) --- crates/ecstore/src/admin_server_info.rs | 3 +- .../bucket/lifecycle/bucket_lifecycle_ops.rs | 4 +-- crates/ecstore/src/bucket/metadata.rs | 2 +- .../replication/replication_resyncer.rs | 2 +- crates/ecstore/src/data_usage.rs | 2 +- crates/ecstore/src/lib.rs | 7 ----- crates/ecstore/src/metrics_realtime.rs | 3 +- crates/ecstore/src/notification_sys.rs | 4 +-- crates/ecstore/src/pools.rs | 2 +- crates/ecstore/src/tier/tier.rs | 2 +- docs/architecture/crate-boundaries.md | 2 ++ docs/architecture/migration-progress.md | 30 +++++++++++++++++-- scripts/check_architecture_migration_rules.sh | 5 ++++ 13 files changed, 46 insertions(+), 22 deletions(-) diff --git a/crates/ecstore/src/admin_server_info.rs b/crates/ecstore/src/admin_server_info.rs index 83cec67ef..b8c7553ad 100644 --- a/crates/ecstore/src/admin_server_info.rs +++ b/crates/ecstore/src/admin_server_info.rs @@ -17,9 +17,8 @@ use crate::error::{Error, Result}; use crate::rpc::{TonicInterceptor, gen_tonic_signature_interceptor, node_service_time_out_client}; use crate::{ disk::endpoint::Endpoint, - global::{GLOBAL_BOOT_TIME, GLOBAL_Endpoints, get_global_deployment_id}, + global::{GLOBAL_BOOT_TIME, GLOBAL_Endpoints, get_global_deployment_id, resolve_object_store_handle}, notification_sys::get_global_notification_sys, - resolve_object_store_handle, }; use crate::data_usage::load_data_usage_cache; diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index 021e6f574..a2bc1732d 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -890,7 +890,7 @@ impl TransitionState { tokio::spawn(async move { Self::inc_counter(&state.compensation_running_tasks); state.record_scanner_transition_state(); - let Some(api) = crate::resolve_object_store_handle() else { + let Some(api) = crate::global::resolve_object_store_handle() else { scheduled.lock().unwrap().remove(&bucket); Self::add_counter(&state.compensation_running_tasks, -1); state.record_scanner_transition_state(); @@ -1909,7 +1909,7 @@ pub async fn enqueue_immediate_expiry(oi: &ObjectInfo, src: LcEventSrc) { let Some(lifecycle) = GLOBAL_LifecycleSys.get(&oi.bucket).await else { return; }; - let Some(api) = crate::resolve_object_store_handle() else { + let Some(api) = crate::global::resolve_object_store_handle() else { return; }; diff --git a/crates/ecstore/src/bucket/metadata.rs b/crates/ecstore/src/bucket/metadata.rs index a9283c14c..bc32a36fb 100644 --- a/crates/ecstore/src/bucket/metadata.rs +++ b/crates/ecstore/src/bucket/metadata.rs @@ -20,7 +20,7 @@ use crate::bucket::utils::deserialize; use crate::config::com::{read_config, save_config}; use crate::disk::BUCKET_META_PREFIX; use crate::error::{Error, Result}; -use crate::resolve_object_store_handle; +use crate::global::resolve_object_store_handle; use crate::store::ECStore; use byteorder::{BigEndian, ByteOrder, LittleEndian}; use rustfs_policy::policy::BucketPolicy; diff --git a/crates/ecstore/src/bucket/replication/replication_resyncer.rs b/crates/ecstore/src/bucket/replication/replication_resyncer.rs index 1970eb1b3..1bea41dfb 100644 --- a/crates/ecstore/src/bucket/replication/replication_resyncer.rs +++ b/crates/ecstore/src/bucket/replication/replication_resyncer.rs @@ -31,8 +31,8 @@ use crate::error::{Error, Result, is_err_object_not_found, is_err_version_not_fo use crate::event_notification::{EventArgs, send_event}; use crate::global::GLOBAL_LocalNodeName; use crate::global::get_global_bucket_monitor; +use crate::global::resolve_object_store_handle; use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader}; -use crate::resolve_object_store_handle; use crate::set_disk::get_lock_acquire_timeout; use crate::storage_api_contracts::{EcstoreObjectIO, EcstoreObjectOperations}; use aws_sdk_s3::error::{ProvideErrorMetadata, SdkError}; diff --git a/crates/ecstore/src/data_usage.rs b/crates/ecstore/src/data_usage.rs index 1411dd382..76ec25302 100644 --- a/crates/ecstore/src/data_usage.rs +++ b/crates/ecstore/src/data_usage.rs @@ -789,7 +789,7 @@ pub async fn load_data_usage_cache(store: &crate::set_disk::SetDisks, name: &str pub async fn save_data_usage_cache(cache: &DataUsageCache, name: &str) -> crate::error::Result<()> { use crate::config::com::save_config; use crate::disk::BUCKET_META_PREFIX; - use crate::resolve_object_store_handle; + use crate::global::resolve_object_store_handle; use std::path::Path; let Some(store) = resolve_object_store_handle() else { diff --git a/crates/ecstore/src/lib.rs b/crates/ecstore/src/lib.rs index 2a3954214..644d1cae9 100644 --- a/crates/ecstore/src/lib.rs +++ b/crates/ecstore/src/lib.rs @@ -57,13 +57,6 @@ mod pools_test; mod store_test; mod tier; -pub use global::set_global_endpoints; -pub use global::update_erasure_type; -pub use global::{get_global_lock_client, get_global_lock_clients, set_global_lock_client, set_global_lock_clients}; -pub use global::{new_object_layer_fn, resolve_object_store_handle, set_object_store_resolver}; - -pub use global::GLOBAL_Endpoints; - #[cfg(test)] mod rio_tests { #[test] diff --git a/crates/ecstore/src/metrics_realtime.rs b/crates/ecstore/src/metrics_realtime.rs index dad185f0e..82d517748 100644 --- a/crates/ecstore/src/metrics_realtime.rs +++ b/crates/ecstore/src/metrics_realtime.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{admin_server_info::get_local_server_property, resolve_object_store_handle}; +use crate::admin_server_info::get_local_server_property; +use crate::global::resolve_object_store_handle; use chrono::Utc; use rustfs_common::{GLOBAL_LOCAL_NODE_NAME, GLOBAL_RUSTFS_ADDR, heal_channel::DriveState, metrics::global_metrics}; use rustfs_io_metrics::internode_metrics::global_internode_metrics; diff --git a/crates/ecstore/src/notification_sys.rs b/crates/ecstore/src/notification_sys.rs index f5729cf49..e01e0afee 100644 --- a/crates/ecstore/src/notification_sys.rs +++ b/crates/ecstore/src/notification_sys.rs @@ -13,12 +13,12 @@ // limitations under the License. use crate::admin_server_info::get_commit_id; +use crate::endpoints::EndpointServerPools; use crate::error::{Error, Result}; -use crate::global::{GLOBAL_BOOT_TIME, get_global_endpoints}; +use crate::global::{GLOBAL_BOOT_TIME, get_global_endpoints, resolve_object_store_handle}; use crate::metrics_realtime::{CollectMetricsOpts, MetricType}; use crate::rebalance::RebalSaveOpt; use crate::rpc::PeerRestClient; -use crate::{endpoints::EndpointServerPools, resolve_object_store_handle}; use futures::future::join_all; use lazy_static::lazy_static; use rustfs_madmin::health::{Cpus, MemInfo, OsInfo, Partitions, ProcInfo, SysConfig, SysErrors, SysServices}; diff --git a/crates/ecstore/src/pools.rs b/crates/ecstore/src/pools.rs index b5054d690..80dee6b08 100644 --- a/crates/ecstore/src/pools.rs +++ b/crates/ecstore/src/pools.rs @@ -35,9 +35,9 @@ use crate::error::{ StorageError, is_err_bucket_exists, is_err_bucket_not_found, is_err_data_movement_overwrite, is_err_object_not_found, is_err_operation_canceled, is_err_version_not_found, }; +use crate::global::resolve_object_store_handle; use crate::notification_sys::get_global_notification_sys; use crate::object_api::{GetObjectReader, ObjectOptions}; -use crate::resolve_object_store_handle; use crate::set_disk::SetDisks; use crate::{global::GLOBAL_LifecycleSys, sets::Sets, store::ECStore}; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; diff --git a/crates/ecstore/src/tier/tier.rs b/crates/ecstore/src/tier/tier.rs index ee7c07a53..51694f3ba 100644 --- a/crates/ecstore/src/tier/tier.rs +++ b/crates/ecstore/src/tier/tier.rs @@ -38,7 +38,7 @@ use tracing::{debug, error, info, warn}; use crate::client::admin_handler_utils::AdminError; use crate::error::{Error, Result, StorageError}; -use crate::resolve_object_store_handle; +use crate::global::resolve_object_store_handle; use crate::tier::{ tier_admin::TierCreds, tier_config::{TierConfig, TierType}, diff --git a/docs/architecture/crate-boundaries.md b/docs/architecture/crate-boundaries.md index 4522677f3..2f695de61 100644 --- a/docs/architecture/crate-boundaries.md +++ b/docs/architecture/crate-boundaries.md @@ -140,6 +140,8 @@ boundary is established; outer crates should use `rustfs_ecstore::api::*` instead of legacy root module paths. This includes storage/layout surfaces as well as remaining bitrot, erasure coding, object DTO/reader, event, list, and batch processor root modules once their facade groups exist. +ECStore root `global` re-exports must also stay removed once consumers use +`rustfs_ecstore::api::global` or crate-internal `crate::global` paths. RustFS startup internals must stay crate-private after the startup owner split. Only `startup_entrypoint` remains a public startup module for the binary diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 94af2ab03..70df41426 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -483,6 +483,21 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block coverage, formatting, diff hygiene, Rust risk scan, branch freshness check, pre-commit quality gate, and three-expert review. +- [x] `API-078` Prune ECStore root global re-exports. + - Completed slice: remove the remaining `pub use global::*` compatibility + exports from the ECStore crate root and route internal ECStore users to + `crate::global` directly. + - Acceptance: outer access to ECStore global helpers remains available only + through `rustfs_ecstore::api::global`, internal ECStore modules use the + real owner path, and the migration guard rejects restoring root global + re-exports. + - Must preserve: object-store resolver behavior, endpoint/global lock client + publication, erasure-type updates, tier/notification/data-usage metadata + loading, and existing `api::global` facade names. + - Verification: migration guard, ECStore and RustFS compile coverage, + formatting, diff hygiene, Rust risk scan, branch freshness check, + pre-commit quality gate, and three-expert review. + - [x] `TEST-PRTYPE-001` Check PR type enum consistency. - Acceptance: `./scripts/check_architecture_migration_rules.sh` parses the allowed PR types from [`crate-boundaries.md`](crate-boundaries.md) and fails @@ -3011,14 +3026,23 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | R-069 narrows startup owner item visibility and API-077 removes remaining facade-covered ECStore root modules without runtime logic changes. | -| Migration preservation | passed | `startup_entrypoint` remains the only public startup module; ECStore bitrot, erasure, object, event, list, and batch surfaces now route through `rustfs_ecstore::api`. | -| Testing/verification | passed | ECStore all-target compile, migration/layer/unsafe guards, formatting, diff hygiene, added-line risk scan, and pre-commit gate passed. | +| Quality/architecture | passed | API-078 removes remaining ECStore global root re-exports without runtime logic changes. | +| Migration preservation | passed | Outer access remains through `rustfs_ecstore::api::global`; internal ECStore users route directly to `crate::global`. | +| Testing/verification | passed | ECStore all-target and RustFS lib/bin compile coverage, migration guards, formatting, diff hygiene, added-line risk scan, and pre-commit gate passed. | ## Verification Notes Passed before push: +- Issue #660 API-078 current slice: + - `cargo check -p rustfs-ecstore --all-targets`: passed. + - `cargo check -p rustfs --lib --bins`: passed. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - Rust added-line risk scan on changed Rust files and guard script: passed. + - `make pre-commit`: passed. + - Issue #660 R-069 current slice: - `cargo check -p rustfs --lib`: passed. - `cargo check -p rustfs --bins`: passed. diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 1c88cd6a7..3c8c69fab 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -84,6 +84,7 @@ NESTED_STORE_API_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/nested_store_api_compat_mod UNAPPROVED_STORE_API_COMPAT_ALIAS_HITS_FILE="${TMP_DIR}/unapproved_store_api_compat_alias_hits.txt" PUBLIC_STORE_API_MODULE_HITS_FILE="${TMP_DIR}/public_store_api_module_hits.txt" ECSTORE_PUBLIC_ROOT_MODULE_HITS_FILE="${TMP_DIR}/ecstore_public_root_module_hits.txt" +ECSTORE_PUBLIC_GLOBAL_REEXPORT_HITS_FILE="${TMP_DIR}/ecstore_public_global_reexport_hits.txt" STORE_API_MODULE_PATH_HITS_FILE="${TMP_DIR}/store_api_module_path_hits.txt" ECSTORE_COMPAT_PASSTHROUGH_EXPECTED_FILE="${TMP_DIR}/ecstore_compat_passthrough_expected.txt" ECSTORE_COMPAT_PASSTHROUGH_ACTUAL_FILE="${TMP_DIR}/ecstore_compat_passthrough_actual.txt" @@ -801,6 +802,10 @@ if rg -n --no-heading '^\s*pub\s+mod\s+(batch_processor|bitrot|erasure_coding|ev report_failure "facade-covered ECStore root modules must remain private; expose compatibility through rustfs_ecstore::api: $(paste -sd '; ' "$ECSTORE_PUBLIC_ROOT_MODULE_HITS_FILE")" fi +if rg -n --no-heading '^\s*pub\s+use\s+global::' "$ROOT_DIR/crates/ecstore/src/lib.rs" >"$ECSTORE_PUBLIC_GLOBAL_REEXPORT_HITS_FILE"; then + report_failure "ECStore global root re-exports must remain private; expose compatibility through rustfs_ecstore::api::global: $(paste -sd '; ' "$ECSTORE_PUBLIC_GLOBAL_REEXPORT_HITS_FILE")" +fi + ( cd "$ROOT_DIR" {