From 9a8a82e90cf3065146c00185bd749087201fb200 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Tue, 30 Jun 2026 07:17:51 +0800 Subject: [PATCH] test(architecture): guard owner cache globals (#4102) --- docs/architecture/global-state-inventory.md | 17 ++++ scripts/check_architecture_migration_rules.sh | 91 +++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/docs/architecture/global-state-inventory.md b/docs/architecture/global-state-inventory.md index a7c82a595..5b09112dc 100644 --- a/docs/architecture/global-state-inventory.md +++ b/docs/architecture/global-state-inventory.md @@ -62,6 +62,23 @@ migration PR removes or replaces each item. | `GLOBAL_BUCKET_TARGET_SYS` | `crates/ecstore/src/bucket/bucket_target_sys.rs`, admin/app/scanner/replication target paths | Runtime migration target / owner helper | Direct static access now stays inside the ECStore bucket target owner; callers still use `BucketTargetSys::get()` until bucket target ownership moves behind a runtime-source or replication target boundary. | | `USAGE_MEMORY_CACHE`, `USAGE_CACHE_UPDATING` | `crates/ecstore/src/data_usage/mod.rs` | Runtime migration target / owner-local cache | Data-usage memory overlay and singleflight state stay private to the ECStore data-usage owner; callers use data-usage functions until scanner/data-usage ownership moves behind an injected runtime context. | +## Owner-Local Cache Inventory + +These owner-local caches and static guards are part of the broad issue #730 +`OnceLock` audit, but they are not runtime ownership handles. They stay private +to the defining owner module; callers must use the existing owner APIs instead +of reaching across module boundaries. + +| State | Owner boundary | Category | Migration stance | +|---|---|---|---| +| `READ_REPAIR_HEAL_CACHE` | `crates/ecstore/src/set_disk/read.rs` | Cache or constant / owner-local cache | Read-repair heal suppression stays local to set-disk read handling. | +| `DISK_COMPRESSION_CONFIG` | `crates/ecstore/src/io_support/compress.rs` | Cache or constant / owner-local cache | Disk compression environment parsing stays local to IO support compression helpers. | +| `CACHED_MAX_INFLIGHT_BYTES`, `CACHED_BATCH_BLOCKS`, `CACHED_BYTESMUT_INGEST` | `crates/ecstore/src/erasure/coding/encode.rs` | Cache or constant / owner-local cache | Erasure encode tuning caches stay local to the coding owner. | +| `CACHED_PUT_LARGE_BATCH_MIN_SIZE_BYTES`, `CACHED_MULTIPART_PUT_LARGE_BATCH_MIN_SIZE_BYTES`, `OBJECT_LOCK_DIAG_ENABLED` | `crates/ecstore/src/set_disk/mod.rs` | Cache or constant / owner-local cache | Set-disk batching and diagnostics caches stay local to the set-disk owner. | +| `DRIVE_TIMEOUT_PROFILE_CACHE`, `DRIVE_TIMEOUT_HEALTH_POLICY_CACHE` | `crates/ecstore/src/disk/disk_store.rs` | Cache or constant / owner-local cache | Drive timeout environment caches stay local to the disk-store owner. | +| `TIER_FREE_VERSION_RECOVERY_STARTED`, `TIER_DELETE_JOURNAL_RECOVERY_STARTED` | `crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs` | Cache or constant / owner-local static guard | Lifecycle recovery single-run guards stay local to lifecycle operations. | +| `REMOTE_DELETE_INFLIGHT`, `REMOTE_DELETE_LIMITER`, `REMOTE_DELETE_BREAKER`, `REMOTE_TIER_DELETE_TEST_HOOK` | `crates/ecstore/src/bucket/lifecycle/tier_sweeper.rs` | Cache or constant / owner-local static guard | Remote tier delete concurrency, breaker, and test hook state stay local to the tier sweeper owner. | + ## First Code-Bearing Candidate `GLOBAL_EXPIRY_STATE` is the safest first runtime migration candidate: diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index a029417b7..2150799f8 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -206,6 +206,13 @@ GLOBAL_BUCKET_TARGET_SYS_BYPASS_HITS_FILE="${TMP_DIR}/global_bucket_target_sys_b EVENT_DISPATCH_HOOK_BYPASS_HITS_FILE="${TMP_DIR}/event_dispatch_hook_bypass_hits.txt" DATA_USAGE_MEMORY_GLOBAL_BYPASS_HITS_FILE="${TMP_DIR}/data_usage_memory_global_bypass_hits.txt" WORKLOAD_ADMISSION_PROVIDER_BYPASS_HITS_FILE="${TMP_DIR}/workload_admission_provider_bypass_hits.txt" +ECSTORE_READ_REPAIR_CACHE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_read_repair_cache_bypass_hits.txt" +ECSTORE_DISK_COMPRESSION_CACHE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_disk_compression_cache_bypass_hits.txt" +ECSTORE_ERASURE_CODING_CACHE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_erasure_coding_cache_bypass_hits.txt" +ECSTORE_SET_DISK_CACHE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_set_disk_cache_bypass_hits.txt" +ECSTORE_DRIVE_TIMEOUT_CACHE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_drive_timeout_cache_bypass_hits.txt" +ECSTORE_LIFECYCLE_RECOVERY_GUARD_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_lifecycle_recovery_guard_bypass_hits.txt" +ECSTORE_REMOTE_TIER_DELETE_STATE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_remote_tier_delete_state_bypass_hits.txt" GLOBAL_BUCKET_MONITOR_BYPASS_HITS_FILE="${TMP_DIR}/global_bucket_monitor_bypass_hits.txt" GLOBAL_ENDPOINTS_BYPASS_HITS_FILE="${TMP_DIR}/global_endpoints_bypass_hits.txt" GLOBAL_IS_ERASURE_BYPASS_HITS_FILE="${TMP_DIR}/global_is_erasure_bypass_hits.txt" @@ -2585,6 +2592,90 @@ if [[ -s "$WORKLOAD_ADMISSION_PROVIDER_BYPASS_HITS_FILE" ]]; then report_failure "WORKLOAD_ADMISSION_SNAPSHOT_PROVIDER access must stay behind ECStore runtime-source helpers: $(paste -sd '; ' "$WORKLOAD_ADMISSION_PROVIDER_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename '\bREAD_REPAIR_HEAL_CACHE\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/set_disk/read\.rs:' || true +) >"$ECSTORE_READ_REPAIR_CACHE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_READ_REPAIR_CACHE_BYPASS_HITS_FILE" ]]; then + report_failure "READ_REPAIR_HEAL_CACHE access must stay behind ECStore set-disk read owner helpers: $(paste -sd '; ' "$ECSTORE_READ_REPAIR_CACHE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\bDISK_COMPRESSION_CONFIG\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/io_support/compress\.rs:' || true +) >"$ECSTORE_DISK_COMPRESSION_CACHE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_DISK_COMPRESSION_CACHE_BYPASS_HITS_FILE" ]]; then + report_failure "DISK_COMPRESSION_CONFIG access must stay behind ECStore IO compression owner helpers: $(paste -sd '; ' "$ECSTORE_DISK_COMPRESSION_CACHE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\bCACHED_(MAX_INFLIGHT_BYTES|BATCH_BLOCKS|BYTESMUT_INGEST)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/erasure/coding/encode\.rs:' || true +) >"$ECSTORE_ERASURE_CODING_CACHE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_ERASURE_CODING_CACHE_BYPASS_HITS_FILE" ]]; then + report_failure "erasure coding cache access must stay behind ECStore erasure coding owner helpers: $(paste -sd '; ' "$ECSTORE_ERASURE_CODING_CACHE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\b(CACHED_(PUT_LARGE_BATCH_MIN_SIZE_BYTES|MULTIPART_PUT_LARGE_BATCH_MIN_SIZE_BYTES)|OBJECT_LOCK_DIAG_ENABLED)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/set_disk/mod\.rs:' || true +) >"$ECSTORE_SET_DISK_CACHE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_SET_DISK_CACHE_BYPASS_HITS_FILE" ]]; then + report_failure "set-disk cache access must stay behind ECStore set-disk owner helpers: $(paste -sd '; ' "$ECSTORE_SET_DISK_CACHE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\bDRIVE_TIMEOUT_(PROFILE_CACHE|HEALTH_POLICY_CACHE)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/disk/disk_store\.rs:' || true +) >"$ECSTORE_DRIVE_TIMEOUT_CACHE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_DRIVE_TIMEOUT_CACHE_BYPASS_HITS_FILE" ]]; then + report_failure "drive timeout cache access must stay behind ECStore disk-store owner helpers: $(paste -sd '; ' "$ECSTORE_DRIVE_TIMEOUT_CACHE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\bTIER_(FREE_VERSION_RECOVERY_STARTED|DELETE_JOURNAL_RECOVERY_STARTED)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops\.rs:' || true +) >"$ECSTORE_LIFECYCLE_RECOVERY_GUARD_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_LIFECYCLE_RECOVERY_GUARD_BYPASS_HITS_FILE" ]]; then + report_failure "lifecycle recovery guard access must stay behind ECStore lifecycle operation owner helpers: $(paste -sd '; ' "$ECSTORE_LIFECYCLE_RECOVERY_GUARD_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename '\b(REMOTE_DELETE_(INFLIGHT|LIMITER|BREAKER)|REMOTE_TIER_DELETE_TEST_HOOK)\b' \ + crates rustfs fuzz \ + --glob '*.rs' | + rg -v '^crates/ecstore/src/bucket/lifecycle/tier_sweeper\.rs:' || true +) >"$ECSTORE_REMOTE_TIER_DELETE_STATE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_REMOTE_TIER_DELETE_STATE_BYPASS_HITS_FILE" ]]; then + report_failure "remote tier delete state access must stay behind ECStore tier sweeper owner helpers: $(paste -sd '; ' "$ECSTORE_REMOTE_TIER_DELETE_STATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename '\bGLOBAL_BUCKET_MONITOR\b' \