From e012d1e7993e16010eca1a2ed2f07b3a45942cca Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Mon, 29 Jun 2026 14:21:31 +0800 Subject: [PATCH] refactor(runtime): wrap boot time global (#4044) --- crates/ecstore/src/api/mod.rs | 4 ++-- crates/ecstore/src/runtime/sources.rs | 9 ++++++--- docs/architecture/global-state-inventory.md | 2 +- rustfs/src/storage/storage_api.rs | 8 ++++++-- scripts/check_architecture_migration_rules.sh | 13 +++++++++++++ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/crates/ecstore/src/api/mod.rs b/crates/ecstore/src/api/mod.rs index e6e1b3ac5..efc2242b0 100644 --- a/crates/ecstore/src/api/mod.rs +++ b/crates/ecstore/src/api/mod.rs @@ -112,7 +112,7 @@ pub mod event { pub mod global { pub use crate::runtime::global::{ - GLOBAL_BOOT_TIME, GLOBAL_LOCAL_DISK_MAP, GLOBAL_TierConfigMgr, get_global_bucket_monitor, get_global_deployment_id, + GLOBAL_LOCAL_DISK_MAP, GLOBAL_TierConfigMgr, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, get_global_lock_client, get_global_lock_clients, get_global_region, get_global_tier_config_mgr, global_rustfs_port, is_dist_erasure, is_erasure, is_erasure_sd, is_first_cluster_node_local, new_object_layer_fn, resolve_object_store_handle, set_global_endpoints, set_global_region, set_global_rustfs_port, set_object_store_resolver, @@ -122,7 +122,7 @@ pub mod global { pub mod runtime { pub use crate::runtime::sources::{ - bucket_monitor, expiry_state_handle, first_cluster_node_is_local, global_tier_config_mgr, local_disk_map_read, + boot_time, bucket_monitor, expiry_state_handle, first_cluster_node_is_local, global_tier_config_mgr, local_disk_map_read, object_store_handle, setup_is_erasure, setup_is_erasure_sd, transition_state_handle, }; } diff --git a/crates/ecstore/src/runtime/sources.rs b/crates/ecstore/src/runtime/sources.rs index ceb8b3193..a50486307 100644 --- a/crates/ecstore/src/runtime/sources.rs +++ b/crates/ecstore/src/runtime/sources.rs @@ -186,10 +186,13 @@ pub(crate) async fn rustfs_addr() -> String { rustfs_common::get_global_addr().await } +pub fn boot_time() -> Option { + GLOBAL_BOOT_TIME.get().cloned() +} + pub(crate) fn boot_uptime_secs() -> u64 { - GLOBAL_BOOT_TIME - .get() - .and_then(|boot_time| SystemTime::now().duration_since(*boot_time).ok()) + boot_time() + .and_then(|boot_time| SystemTime::now().duration_since(boot_time).ok()) .unwrap_or_default() .as_secs() } diff --git a/docs/architecture/global-state-inventory.md b/docs/architecture/global-state-inventory.md index afa611538..eb87fcb81 100644 --- a/docs/architecture/global-state-inventory.md +++ b/docs/architecture/global-state-inventory.md @@ -46,7 +46,7 @@ migration PR removes or replaces each item. | `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 | Move through config/runtime-source owners only; do not combine with storage-class behavior or persistence changes. | | `GLOBAL_EventNotifier`, `GLOBAL_NotificationSys` | `crates/ecstore/src/services/*` | Runtime migration target | Preserve notification and audit side effects; move only through notify/runtime-source boundaries. | -| `GLOBAL_BOOT_TIME`, `globalDeploymentIDPtr`, `GLOBAL_REGION`, `GLOBAL_RUSTFS_PORT`, `GLOBAL_LocalNodeName` | `crates/ecstore/src/runtime/global.rs` | Runtime migration target | Scalar handles may migrate in small PRs after call sites use AppContext or owner-local runtime-source readers. | +| `GLOBAL_BOOT_TIME`, `globalDeploymentIDPtr`, `GLOBAL_REGION`, `GLOBAL_RUSTFS_PORT`, `GLOBAL_LocalNodeName` | `crates/ecstore/src/runtime/global.rs`, `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Boot time reads now go through the ECStore runtime-source API; the remaining scalar handles may migrate in small PRs after call sites use AppContext or owner-local runtime-source readers. | | `GLOBAL_LOCAL_LOCK_CLIENT`, `GLOBAL_LOCK_CLIENTS`, `GLOBAL_LOCK_MANAGER` | `crates/ecstore/src/runtime/global.rs`, `crates/lock` | Runtime migration target / process-global split | Preserve lock quorum and lock client selection; keep process-level lock manager separate from ECStore endpoint-specific clients. | | `GLOBAL_CONN_MAP`, `GLOBAL_LOCAL_NODE_NAME`, `GLOBAL_RUSTFS_HOST`, `GLOBAL_RUSTFS_ADDR`, `GLOBAL_ROOT_CERT`, `GLOBAL_MTLS_IDENTITY`, `GLOBAL_OUTBOUND_TLS_GENERATION` | `crates/common`, `crates/tls-runtime`, `crates/ecstore/src/runtime/sources.rs` | Runtime migration target / process-global split | Internode connection cache, common local node name, RustFS host/address reads, and outbound TLS material reads are now owned behind `rustfs_common` helpers; migrate the remaining transport and TLS state only after internode transport and outbound TLS ownership are explicit, without changing cached channel reuse or TLS reload semantics. | | `GLOBAL_RUSTFS_RPC_SECRET` | `crates/credentials`, `crates/ecstore/src/runtime/sources.rs` | Runtime migration target / process-global split | RPC auth token writes now stay behind the `rustfs_credentials` helper boundary; migrate only if runtime secret ownership changes, preserving lazy environment and credential-derived token semantics. | diff --git a/rustfs/src/storage/storage_api.rs b/rustfs/src/storage/storage_api.rs index 5f09d0ae3..9e2aa9a5f 100644 --- a/rustfs/src/storage/storage_api.rs +++ b/rustfs/src/storage/storage_api.rs @@ -378,13 +378,17 @@ pub(crate) mod ecstore_global { #[cfg(test)] pub(crate) use rustfs_ecstore::api::global::new_object_layer_fn; pub(crate) use rustfs_ecstore::api::global::{ - GLOBAL_BOOT_TIME, GLOBAL_TierConfigMgr, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, + GLOBAL_TierConfigMgr, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, get_global_lock_client, get_global_lock_clients, get_global_region, get_global_tier_config_mgr, global_rustfs_port, is_dist_erasure, set_global_endpoints, set_global_region, set_global_rustfs_port, set_object_store_resolver, shutdown_background_services, update_erasure_type, }; } +pub(crate) mod ecstore_runtime { + pub(crate) use rustfs_ecstore::api::runtime::boot_time; +} + #[allow(unused_imports)] pub(crate) mod ecstore_layout { pub(crate) use rustfs_ecstore::api::layout::{DisksLayout, EndpointServerPools, Endpoints, PoolEndpoints, SetupType}; @@ -568,7 +572,7 @@ pub(crate) fn get_global_replication_stats() -> Option> { } pub(crate) fn get_global_boot_time() -> Option { - ecstore_global::GLOBAL_BOOT_TIME.get().cloned() + ecstore_runtime::boot_time() } pub(crate) fn get_daily_all_tier_stats() -> DailyAllTierStats { diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 3a9bcb985..9289fa121 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -182,6 +182,7 @@ EXTERNAL_TEST_ECSTORE_COMPAT_BYPASS_HITS_FILE="${TMP_DIR}/external_test_ecstore_ FUZZ_ECSTORE_COMPAT_BYPASS_HITS_FILE="${TMP_DIR}/fuzz_ecstore_compat_bypass_hits.txt" 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_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" GLOBAL_RUSTFS_ADDR_BYPASS_HITS_FILE="${TMP_DIR}/global_rustfs_addr_bypass_hits.txt" @@ -2295,6 +2296,18 @@ if [[ -s "$REPLICATION_FACADE_BYPASS_HITS_FILE" ]]; then report_failure "replication facade imports must stay in local storage_api boundaries: $(paste -sd '; ' "$REPLICATION_FACADE_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename '\bGLOBAL_BOOT_TIME\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/runtime/(global|sources)\.rs:' || true +) >"$GLOBAL_BOOT_TIME_BYPASS_HITS_FILE" + +if [[ -s "$GLOBAL_BOOT_TIME_BYPASS_HITS_FILE" ]]; then + report_failure "GLOBAL_BOOT_TIME access must stay behind ECStore runtime-source helpers: $(paste -sd '; ' "$GLOBAL_BOOT_TIME_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename '\bGLOBAL_CONN_MAP\b' \