From 74aef760f0b6bf584beaf7dd7624e0d779b86bc3 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Tue, 30 Jun 2026 05:29:10 +0800 Subject: [PATCH] refactor(lifecycle): normalize state global names (#4096) --- .../src/bucket/lifecycle/bucket_lifecycle_ops.rs | 8 ++++---- crates/ecstore/src/runtime/sources.rs | 6 +++--- docs/architecture/global-state-inventory.md | 6 +++--- scripts/check_architecture_migration_rules.sh | 15 ++++++++++++++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index 5e3fca5c6..bd92a06ad 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -120,16 +120,16 @@ const DATE_EXPIRY_EXISTING_OBJECTS_GRACE_SECS: i64 = 5; const EXPIRY_WORKER_QUEUE_CAPACITY: usize = 1000; lazy_static! { - pub static ref GLOBAL_ExpiryState: Arc> = ExpiryState::new(); - pub static ref GLOBAL_TransitionState: Arc = TransitionState::new(); + pub static ref GLOBAL_EXPIRY_STATE: Arc> = ExpiryState::new(); + pub static ref GLOBAL_TRANSITION_STATE: Arc = TransitionState::new(); } pub fn get_global_expiry_state() -> Arc> { - GLOBAL_ExpiryState.clone() + GLOBAL_EXPIRY_STATE.clone() } pub fn get_global_transition_state() -> Arc { - GLOBAL_TransitionState.clone() + GLOBAL_TRANSITION_STATE.clone() } fn resolve_transition_worker_count() -> (i64, i64, i64) { diff --git a/crates/ecstore/src/runtime/sources.rs b/crates/ecstore/src/runtime/sources.rs index 2df07d0cb..dc89809d7 100644 --- a/crates/ecstore/src/runtime/sources.rs +++ b/crates/ecstore/src/runtime/sources.rs @@ -21,7 +21,7 @@ use std::{ use crate::bucket::bandwidth::monitor::Monitor; use crate::disk::endpoint::Endpoint; use crate::{ - bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, GLOBAL_ExpiryState, GLOBAL_TransitionState, TransitionState}, + bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, GLOBAL_EXPIRY_STATE, GLOBAL_TRANSITION_STATE, TransitionState}, bucket::metadata_sys::{BucketMetadataSys, get_global_bucket_metadata_sys}, bucket::replication::{DynReplicationPool, GLOBAL_REPLICATION_POOL, GLOBAL_REPLICATION_STATS, ReplicationStats}, config::{get_global_storage_class, set_global_storage_class, storageclass}, @@ -388,11 +388,11 @@ pub(crate) fn tier_config_mgr_handle() -> Arc> { } pub fn expiry_state_handle() -> Arc> { - GLOBAL_ExpiryState.clone() + GLOBAL_EXPIRY_STATE.clone() } pub fn transition_state_handle() -> Arc { - GLOBAL_TransitionState.clone() + GLOBAL_TRANSITION_STATE.clone() } pub(crate) fn event_notifier_handle() -> Arc> { diff --git a/docs/architecture/global-state-inventory.md b/docs/architecture/global-state-inventory.md index ba75993b7..8ab7538f1 100644 --- a/docs/architecture/global-state-inventory.md +++ b/docs/architecture/global-state-inventory.md @@ -29,7 +29,7 @@ caches separate from runtime migration targets. | Owner-local compatibility | Existing compatibility adapters that are allowed to read globals while callers migrate to AppContext-first or owner-local runtime-source APIs. | `rustfs/src/*/runtime_sources.rs`, `rustfs/src/*/storage_api.rs`, `crates/*/storage_api.rs` | | Test or fixture state | Static setup used by tests to amortize expensive ECStore setup or isolate compatibility harness state. | `rustfs/src/app/*_test.rs`, `crates/scanner/tests/*`, `crates/ecstore/src/**/tests` | | Cache or constant | Regexes, metrics descriptors, defaults, KVS registrations, headers, path constants, and small process caches that are not runtime ownership handles. | `crates/config`, `crates/obs/src/metrics`, `crates/utils`, `rustfs/src/server/readiness.rs` | -| Legacy naming or review-needed | Remaining mixed-case `GLOBAL_*`, old MinIO-port naming, stale comments, or names that need owner confirmation before code movement. | `GLOBAL_ExpiryState`, `GLOBAL_TransitionState`, `GLOBAL_OBJECT_API` | +| Legacy naming or review-needed | Remaining mixed-case `GLOBAL_*`, old MinIO-port naming, stale comments, or names that need owner confirmation before code movement. | `GLOBAL_NotificationSys`, `GLOBAL_OBJECT_API` | ## Runtime Migration Inventory @@ -42,7 +42,7 @@ migration PR removes or replaces each item. | `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_IS_ERASURE`, `GLOBAL_IS_DIST_ERASURE`, `GLOBAL_IS_ERASURE_SD`, `GLOBAL_ROOT_DISK_THRESHOLD` | `crates/ecstore/src/runtime/global.rs` and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Endpoint, setup-type, and root-disk-threshold access now stays behind ECStore runtime helpers; move endpoint ownership only after readiness and quorum behavior have explicit coverage. | | `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, disk-id cache, and set-drive access now stay behind ECStore runtime-source helpers instead of direct global access; preserve disk lookup, remote/local classification, and test reset hooks in later ownership changes. | -| `GLOBAL_ExpiryState`, `GLOBAL_TransitionState`, `GLOBAL_LIFECYCLE_SYS` | `crates/ecstore/src/bucket/lifecycle/*`, `crates/ecstore/src/runtime/global.rs`, and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | `GLOBAL_LIFECYCLE_SYS` access now stays behind ECStore runtime-source helpers; scanner expiry-state access now uses the ECStore runtime `expiry_state_handle` boundary; `GLOBAL_ExpiryState` remains the first code-bearing ownership candidate because AppContext already has an `ExpiryStateInterface`, resolver, and tests. | +| `GLOBAL_EXPIRY_STATE`, `GLOBAL_TRANSITION_STATE`, `GLOBAL_LIFECYCLE_SYS` | `crates/ecstore/src/bucket/lifecycle/*`, `crates/ecstore/src/runtime/global.rs`, and `crates/ecstore/src/runtime/sources.rs` | Runtime migration target | Lifecycle state globals now stay behind ECStore lifecycle owner helpers and ECStore runtime-source helpers; scanner expiry-state access now uses the ECStore runtime `expiry_state_handle` boundary; `GLOBAL_EXPIRY_STATE` remains the first code-bearing ownership candidate 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 | Replication pool/stat access now stays behind replication owner and ECStore runtime-source helpers; bucket-monitor direct access now stays behind ECStore runtime helpers while AppContext/runtime-source resolvers remain the caller boundary. | | `GLOBAL_TIER_CONFIG_MGR`, `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. | | `GLOBAL_EVENT_NOTIFIER`, `GLOBAL_NotificationSys` | `crates/ecstore/src/runtime/global.rs`, `crates/ecstore/src/runtime/sources.rs`, and `crates/ecstore/src/services/*` | Runtime migration target | `GLOBAL_EVENT_NOTIFIER` access now stays behind ECStore runtime-source helpers; move remaining notification ownership only through notify/runtime-source boundaries. | @@ -60,7 +60,7 @@ migration PR removes or replaces each item. ## First Code-Bearing Candidate -`GLOBAL_ExpiryState` is the safest first runtime migration candidate: +`GLOBAL_EXPIRY_STATE` is the safest first runtime migration candidate: - AppContext already exposes `ExpiryStateInterface` and resolver coverage in `rustfs/src/app/context.rs`. diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index eedbdb2e6..362944cbb 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -70,7 +70,7 @@ require_source_contains "docs/architecture/global-state-crate-split-plan.md" "ru require_source_contains "docs/architecture/global-state-crate-split-plan.md" "global-state-inventory.md" "global state inventory plan link" require_source_contains "docs/architecture/global-state-inventory.md" "## Global State Classification" "global state inventory classification section" require_source_contains "docs/architecture/global-state-inventory.md" "## Runtime Migration Inventory" "global state inventory migration section" -require_source_contains "docs/architecture/global-state-inventory.md" "GLOBAL_ExpiryState" "global state inventory first candidate" +require_source_contains "docs/architecture/global-state-inventory.md" "GLOBAL_EXPIRY_STATE" "global state inventory first candidate" require_source_contains "docs/architecture/obs-ecstore-dependency-inventory.md" "## Dependency Inventory" "observability ECStore dependency inventory section" require_source_contains "docs/architecture/obs-ecstore-dependency-inventory.md" "## Extraction Plan" "observability ECStore extraction plan section" require_source_contains "docs/architecture/obs-ecstore-dependency-inventory.md" "crates/obs/src/metrics/storage_api.rs" "observability ECStore storage_api boundary" @@ -207,6 +207,7 @@ GLOBAL_LOCAL_DISK_ID_MAP_BYPASS_HITS_FILE="${TMP_DIR}/global_local_disk_id_map_b GLOBAL_LOCAL_DISK_SET_DRIVES_BYPASS_HITS_FILE="${TMP_DIR}/global_local_disk_set_drives_bypass_hits.txt" GLOBAL_ERASURE_SD_BYPASS_HITS_FILE="${TMP_DIR}/global_erasure_sd_bypass_hits.txt" GLOBAL_ROOT_DISK_THRESHOLD_BYPASS_HITS_FILE="${TMP_DIR}/global_root_disk_threshold_bypass_hits.txt" +GLOBAL_LIFECYCLE_STATE_BYPASS_HITS_FILE="${TMP_DIR}/global_lifecycle_state_bypass_hits.txt" GLOBAL_LIFECYCLE_SYS_BYPASS_HITS_FILE="${TMP_DIR}/global_lifecycle_sys_bypass_hits.txt" GLOBAL_EVENT_NOTIFIER_BYPASS_HITS_FILE="${TMP_DIR}/global_event_notifier_bypass_hits.txt" GLOBAL_BOOT_TIME_BYPASS_HITS_FILE="${TMP_DIR}/global_boot_time_bypass_hits.txt" @@ -2635,6 +2636,18 @@ if [[ -s "$GLOBAL_ROOT_DISK_THRESHOLD_BYPASS_HITS_FILE" ]]; then report_failure "GLOBAL_ROOT_DISK_THRESHOLD access must stay behind ECStore runtime-source helpers: $(paste -sd '; ' "$GLOBAL_ROOT_DISK_THRESHOLD_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename '\bGLOBAL_(ExpiryState|EXPIRY_STATE|TransitionState|TRANSITION_STATE)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/(bucket/lifecycle/bucket_lifecycle_ops|runtime/sources)\.rs:' || true +) >"$GLOBAL_LIFECYCLE_STATE_BYPASS_HITS_FILE" + +if [[ -s "$GLOBAL_LIFECYCLE_STATE_BYPASS_HITS_FILE" ]]; then + report_failure "lifecycle state globals must stay behind ECStore lifecycle owner and runtime-source helpers: $(paste -sd '; ' "$GLOBAL_LIFECYCLE_STATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename '\bGLOBAL_(LifecycleSys|LIFECYCLE_SYS)\b' \