From ecbc5385d3d2e79d4a7d554199ecec1734054e91 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Mon, 29 Jun 2026 16:33:36 +0800 Subject: [PATCH] refactor(runtime): hide local disk id global (#4047) --- crates/ecstore/src/runtime/sources.rs | 5 +++++ crates/ecstore/src/store/mod.rs | 10 ++++------ docs/architecture/global-state-inventory.md | 2 +- scripts/check_architecture_migration_rules.sh | 13 +++++++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/ecstore/src/runtime/sources.rs b/crates/ecstore/src/runtime/sources.rs index a50486307..2bdb810c2 100644 --- a/crates/ecstore/src/runtime/sources.rs +++ b/crates/ecstore/src/runtime/sources.rs @@ -401,6 +401,11 @@ pub(crate) async fn local_disk_path_by_id(disk_id: &Uuid) -> Option { GLOBAL_LOCAL_DISK_ID_MAP.read().await.get(disk_id).cloned() } +#[cfg(test)] +pub(crate) async fn clear_local_disk_id_map_for_test() { + GLOBAL_LOCAL_DISK_ID_MAP.write().await.clear(); +} + pub(crate) async fn record_local_disk_id(disk_id: Uuid, endpoint: String) { GLOBAL_LOCAL_DISK_ID_MAP.write().await.insert(disk_id, endpoint); } diff --git a/crates/ecstore/src/store/mod.rs b/crates/ecstore/src/store/mod.rs index 7806df702..a0fd9b783 100644 --- a/crates/ecstore/src/store/mod.rs +++ b/crates/ecstore/src/store/mod.rs @@ -755,7 +755,8 @@ impl crate::storage_api_contracts::admin::StorageAdminApi for ECStore { mod tests { use super::*; use crate::layout::endpoints::{Endpoints, PoolEndpoints}; - use crate::runtime::global::{GLOBAL_LOCAL_DISK_ID_MAP, reset_local_disk_test_state}; + use crate::runtime::global::reset_local_disk_test_state; + use crate::runtime::sources::{clear_local_disk_id_map_for_test, local_disk_path_by_id}; use crate::store::init_format::{connect_load_init_formats, init_disks}; use serial_test::serial; use tempfile::TempDir; @@ -832,7 +833,7 @@ mod tests { .await .expect("initialize format metadata"); - GLOBAL_LOCAL_DISK_ID_MAP.write().await.clear(); + clear_local_disk_id_map_for_test().await; let local_disks = all_local_disk().await; let first_disk = local_disks.first().expect("local disk exists"); @@ -844,10 +845,7 @@ mod tests { let found = find_local_disk_by_ref(&disk_id.to_string()).await; assert!(found.is_some(), "disk lookup by id should backfill cache"); - assert_eq!( - GLOBAL_LOCAL_DISK_ID_MAP.read().await.get(&disk_id).cloned(), - Some(first_disk.endpoint().to_string()) - ); + assert_eq!(local_disk_path_by_id(&disk_id).await, Some(first_disk.endpoint().to_string())); reset_local_disk_test_state().await; } diff --git a/docs/architecture/global-state-inventory.md b/docs/architecture/global-state-inventory.md index 73c205d4d..e567be24d 100644 --- a/docs/architecture/global-state-inventory.md +++ b/docs/architecture/global-state-inventory.md @@ -41,7 +41,7 @@ migration PR removes or replaces each item. | `APP_CONTEXT_SINGLETON` | `rustfs/src/app/context/global.rs` | Owner-local compatibility | Keep as the context-first facade while no-context startup and embedded callers still exist. | | `GLOBAL_OBJECT_API`, `GLOBAL_OBJECT_STORE_RESOLVER` | `crates/ecstore/src/runtime/global.rs` | Runtime migration target | Do not migrate first; it is tied to storage startup, IAM-after-storage AppContext publication, and data-plane resolver compatibility. | | `GLOBAL_Endpoints`, `GLOBAL_IsErasure`, `GLOBAL_IsDistErasure`, `GLOBAL_IsErasureSD`, `GLOBAL_RootDiskThreshold` | `crates/ecstore/src/runtime/global.rs` and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Move only after endpoint, setup-type, and root-disk-threshold ownership can be tested without changing readiness or quorum behavior. | -| `GLOBAL_LOCAL_DISK_MAP`, `GLOBAL_LOCAL_DISK_ID_MAP`, `GLOBAL_LOCAL_DISK_SET_DRIVES` | `crates/ecstore/src/runtime/global.rs` and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Local disk map reads now stay behind the ECStore runtime-source helper instead of the global facade; move disk-id and set-drive access separately while preserving disk lookup, remote/local classification, and test reset hooks. | +| `GLOBAL_LOCAL_DISK_MAP`, `GLOBAL_LOCAL_DISK_ID_MAP`, `GLOBAL_LOCAL_DISK_SET_DRIVES` | `crates/ecstore/src/runtime/global.rs` and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Local disk map and disk-id cache reads now stay behind ECStore runtime-source helpers instead of direct global access; move set-drive access separately while preserving disk lookup, remote/local classification, and test reset hooks. | | `GLOBAL_ExpiryState`, `GLOBAL_TransitionState`, `GLOBAL_LifecycleSys` | `crates/ecstore/src/bucket/lifecycle/*` and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | First code-bearing candidate is `GLOBAL_ExpiryState`, because AppContext already has an `ExpiryStateInterface`, resolver, and tests. | | `GLOBAL_REPLICATION_POOL`, `GLOBAL_REPLICATION_STATS`, `GLOBAL_BUCKET_MONITOR` | `crates/ecstore/src/bucket/replication/*`, `crates/ecstore/src/runtime/global.rs` | Runtime migration target | Keep behind AppContext replication and bucket-monitor resolvers until queue admission, stats, and admin reporting coverage are explicit. | | `GLOBAL_TierConfigMgr`, `GLOBAL_STORAGE_CLASS`, `GLOBAL_CONFIG_SYS`, `GLOBAL_SERVER_CONFIG` | `crates/ecstore/src/config`, `crates/config`, `rustfs/src/app/context/runtime_sources.rs` | Runtime migration target | Tier config manager reads and reloads now use the ECStore runtime-source helper; move remaining config state through config/runtime-source owners only, without combining storage-class behavior or persistence changes. | diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index f06fde16a..deec2d64f 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -183,6 +183,7 @@ FUZZ_ECSTORE_COMPAT_BYPASS_HITS_FILE="${TMP_DIR}/fuzz_ecstore_compat_bypass_hits EXTERNAL_ECSTORE_API_BOUNDARY_HITS_FILE="${TMP_DIR}/external_ecstore_api_boundary_hits.txt" REPLICATION_FACADE_BYPASS_HITS_FILE="${TMP_DIR}/replication_facade_bypass_hits.txt" GLOBAL_LOCAL_DISK_MAP_BYPASS_HITS_FILE="${TMP_DIR}/global_local_disk_map_bypass_hits.txt" +GLOBAL_LOCAL_DISK_ID_MAP_BYPASS_HITS_FILE="${TMP_DIR}/global_local_disk_id_map_bypass_hits.txt" GLOBAL_BOOT_TIME_BYPASS_HITS_FILE="${TMP_DIR}/global_boot_time_bypass_hits.txt" GLOBAL_CONN_MAP_BYPASS_HITS_FILE="${TMP_DIR}/global_conn_map_bypass_hits.txt" GLOBAL_LOCAL_NODE_NAME_BYPASS_HITS_FILE="${TMP_DIR}/global_local_node_name_bypass_hits.txt" @@ -2310,6 +2311,18 @@ if [[ -s "$GLOBAL_LOCAL_DISK_MAP_BYPASS_HITS_FILE" ]]; then report_failure "GLOBAL_LOCAL_DISK_MAP access must stay behind ECStore runtime-source helpers: $(paste -sd '; ' "$GLOBAL_LOCAL_DISK_MAP_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename '\bGLOBAL_LOCAL_DISK_ID_MAP\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/runtime/(global|sources)\.rs:' || true +) >"$GLOBAL_LOCAL_DISK_ID_MAP_BYPASS_HITS_FILE" + +if [[ -s "$GLOBAL_LOCAL_DISK_ID_MAP_BYPASS_HITS_FILE" ]]; then + report_failure "GLOBAL_LOCAL_DISK_ID_MAP access must stay behind ECStore runtime-source helpers: $(paste -sd '; ' "$GLOBAL_LOCAL_DISK_ID_MAP_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename '\bGLOBAL_BOOT_TIME\b' \