refactor: centralize server storage runtime sources (#3843)

This commit is contained in:
Zhengchao An
2026-06-25 12:20:53 +08:00
committed by GitHub
parent 839cab47ce
commit 928074a97d
23 changed files with 255 additions and 106 deletions
+22 -4
View File
@@ -5,8 +5,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-startup-runtime-sources`
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203`.
- Branch: `overtrue/arch-server-storage-runtime-source-readers`
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204`.
- Based on: stacked on PR #3828 head after PR #3827.
- PR type for this branch: `consumer-migration`
- Runtime behavior changes: none.
@@ -43,7 +43,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
source helpers, plus AppContext fallback KMS/IAM/ECStore/config/metrics/TLS
runtime source helpers, plus startup/root KMS, credentials, region,
readiness-time, observability, metrics, buffer, and TLS runtime source
helpers,
helpers, plus server readiness/audit/event/module-switch runtime source
helpers and storage request/RPC/SSE runtime source helpers,
through AppContext-first or owner-crate resolver boundaries.
- CI/script changes: lock completed owner and test/fuzz boundaries against
bare/glob imports, scattered raw ECStore facade subpaths, and startup
@@ -54,7 +55,7 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
event-bridge thin module regressions, plus IAM runtime-source bypasses;
accept the reviewed AppContext resolver reverse dependencies in the layer
baseline.
- Docs changes: record the API-136 through API-203 owner facade and lifecycle
- Docs changes: record the API-136 through API-204 owner facade and lifecycle
runtime-source cleanup.
## Phase 0 Tasks
@@ -4920,6 +4921,23 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
global scan, migration/layer guards, fast PR gate, and full PR gate before
PR.
- [x] `API-204` Centralize server and storage runtime source readers.
- Do: route server audit/event/module-switch/readiness/KMS health reads,
startup bucket replication-pool reads, and storage request/RPC/SSE runtime
reads through owner runtime-source boundaries.
- Acceptance: the migrated server/startup/storage files no longer import
AppContext resolvers directly, and migration rules reject reintroducing
those direct resolver reads outside the owner runtime-source modules.
- Must preserve: audit/notify module switch behavior, public health KMS
readiness behavior, dependency readiness cache behavior, bucket metadata
replication resync startup, buffer profile lookup, object-store lookup,
internode metrics recording, local-node naming, request credential/notify
dispatch, performance metrics, encryption service lookup, region lookup,
and IAM authorization behavior.
- Verification: focused RustFS storage/server compile and tests, formatting,
migration/layer guards, diff hygiene, residual direct AppContext scan, Rust
risk scan, fast PR gate, and full PR gate before PR.
## Next PRs
1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries.
+2 -3
View File
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::{module_switch::resolve_audit_module_state, refresh_persisted_module_switches_from_store};
use crate::app::context::resolve_server_config;
use super::{module_switch::resolve_audit_module_state, refresh_persisted_module_switches_from_store, runtime_sources};
use rustfs_audit::{AuditError, AuditResult, audit_system, init_audit_system, system::AuditSystemState};
use std::sync::atomic::{AtomicBool, Ordering};
use tracing::{info, warn};
@@ -21,7 +20,7 @@ use tracing::{info, warn};
static AUDIT_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_AUDIT_ENABLE);
fn server_config_from_context() -> Option<rustfs_config::server_config::Config> {
resolve_server_config()
runtime_sources::server_config()
}
pub fn refresh_audit_module_enabled() -> bool {
+3 -4
View File
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::{module_switch::resolve_notify_module_state, refresh_persisted_module_switches_from_store};
use crate::app::context::{resolve_notify_interface, resolve_server_config};
use super::{module_switch::resolve_notify_module_state, refresh_persisted_module_switches_from_store, runtime_sources};
use crate::storage::{EventArgs as EcstoreEventArgs, StorageObjectInfo, register_event_dispatch_hook};
use chrono::{DateTime, Utc};
use rustfs_notify::{EventArgs as NotifyEventArgs, NotifyObjectInfo};
@@ -26,7 +25,7 @@ use tracing::{error, info, instrument, warn};
static NOTIFY_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_NOTIFY_ENABLE);
fn server_config_from_context() -> Option<rustfs_config::server_config::Config> {
resolve_server_config()
runtime_sources::server_config()
}
pub fn refresh_notify_module_enabled() -> bool {
@@ -118,7 +117,7 @@ fn install_ecstore_event_dispatch_hook() {
return;
};
spawn(async move {
resolve_notify_interface().notify(notify_args).await;
runtime_sources::notify_interface().notify(notify_args).await;
});
});
+2 -2
View File
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::runtime_sources;
use crate::admin::console::is_console_path;
use crate::admin::handlers::health::{HealthProbe, build_health_response_parts};
use crate::app::context::resolve_kms_runtime_service_manager;
use crate::error::ApiError;
use crate::server::RemoteAddr;
use crate::server::cors;
@@ -905,7 +905,7 @@ fn is_public_health_endpoint_request(method: &Method, path: &str) -> bool {
}
async fn health_kms_ready() -> bool {
let Some(service_manager) = resolve_kms_runtime_service_manager() else {
let Some(service_manager) = runtime_sources::kms_runtime_service_manager() else {
return true;
};
+1
View File
@@ -23,6 +23,7 @@ mod module_switch;
mod prefix;
mod readiness;
mod runtime;
pub(crate) mod runtime_sources;
mod service_state;
pub mod tls_material;
+3 -3
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context::resolve_object_store_handle;
use super::runtime_sources;
use crate::storage::{Error as StorageError, read_config, save_config};
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicBool, Ordering};
@@ -159,7 +159,7 @@ pub(crate) fn validate_module_switch_update(requested: PersistedModuleSwitches)
}
pub(crate) async fn refresh_persisted_module_switches_from_store() -> Result<PersistedModuleSwitches, String> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err("storage layer not initialized".to_string());
};
@@ -180,7 +180,7 @@ pub(crate) async fn refresh_persisted_module_switches_from_store() -> Result<Per
}
pub(crate) async fn save_persisted_module_switches_to_store(config: PersistedModuleSwitches) -> Result<(), String> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err("storage layer not initialized".to_string());
};
+7 -9
View File
@@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context::{
resolve_endpoints_handle, resolve_iam_ready, resolve_lock_clients_handle, resolve_object_store_handle,
};
use crate::server::runtime_sources;
use crate::server::{ServiceState, ServiceStateManager};
use crate::server::{has_path_prefix, is_table_catalog_path};
use crate::storage::{Endpoint, EndpointServerPools, is_dist_erasure};
@@ -448,7 +446,7 @@ pub async fn collect_dependency_readiness() -> DependencyReadiness {
}
pub async fn collect_dependency_readiness_report() -> DependencyReadinessReport {
let iam_ready_raw = resolve_iam_ready();
let iam_ready_raw = runtime_sources::iam_ready();
let storage_ready = if let Some(cached) = load_cached_storage_readiness().await {
cached
} else {
@@ -471,7 +469,7 @@ pub async fn collect_dependency_readiness_report() -> DependencyReadinessReport
pub(crate) async fn snapshot_dependency_readiness_report() -> DependencyReadinessReport {
let readiness = DependencyReadiness {
storage_ready: collect_storage_readiness_uncached().await,
iam_ready: resolve_iam_ready(),
iam_ready: runtime_sources::iam_ready(),
lock_quorum_ready: collect_lock_quorum_status_uncached().await.ready,
};
@@ -489,7 +487,7 @@ async fn collect_lock_quorum_status() -> LockQuorumStatus {
}
async fn collect_dependency_readiness_uncached() -> DependencyReadiness {
let iam_ready_raw = resolve_iam_ready();
let iam_ready_raw = runtime_sources::iam_ready();
let storage_ready = collect_storage_readiness_uncached().await;
let lock_quorum_status = collect_lock_quorum_status_uncached().await;
@@ -504,7 +502,7 @@ async fn collect_dependency_readiness_uncached() -> DependencyReadiness {
}
async fn collect_storage_readiness_uncached() -> bool {
if let Some(store) = resolve_object_store_handle() {
if let Some(store) = runtime_sources::object_store_handle() {
let storage_info = StorageAdminApi::storage_info(store.as_ref()).await;
storage_ready_from_runtime_state(&storage_info)
} else {
@@ -595,10 +593,10 @@ async fn collect_lock_quorum_status_uncached() -> LockQuorumStatus {
};
}
let Some(pool_endpoints) = resolve_endpoints_handle() else {
let Some(pool_endpoints) = runtime_sources::endpoints_handle() else {
return LockQuorumStatus::default();
};
let Some(lock_clients) = resolve_lock_clients_handle() else {
let Some(lock_clients) = runtime_sources::lock_clients_handle() else {
return LockQuorumStatus::default();
};
+48
View File
@@ -0,0 +1,48 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context;
use crate::storage::{ECStore, EndpointServerPools};
use rustfs_kms::KmsServiceManager;
use rustfs_lock::LockClient;
use std::collections::HashMap;
use std::sync::Arc;
pub(crate) fn kms_runtime_service_manager() -> Option<Arc<KmsServiceManager>> {
context::resolve_kms_runtime_service_manager()
}
pub(crate) fn server_config() -> Option<rustfs_config::server_config::Config> {
context::resolve_server_config()
}
pub(crate) fn notify_interface() -> Arc<dyn context::NotifyInterface> {
context::resolve_notify_interface()
}
pub(crate) fn object_store_handle() -> Option<Arc<ECStore>> {
context::resolve_object_store_handle()
}
pub(crate) fn iam_ready() -> bool {
context::resolve_iam_ready()
}
pub(crate) fn endpoints_handle() -> Option<EndpointServerPools> {
context::resolve_endpoints_handle()
}
pub(crate) fn lock_clients_handle() -> Option<HashMap<String, Arc<dyn LockClient>>> {
context::resolve_lock_clients_handle()
}
+2 -2
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context::resolve_replication_pool_handle;
use crate::startup_runtime_sources;
use crate::storage::{ECStore, init_bucket_metadata_sys, try_migrate_bucket_metadata, try_migrate_iam_config};
use rustfs_storage_api::{BucketOperations, BucketOptions};
use std::{
@@ -52,7 +52,7 @@ pub(crate) async fn init_bucket_metadata_runtime(store: Arc<ECStore>, ctx: Cance
try_migrate_bucket_metadata(store.clone()).await;
if let Some(pool) = resolve_replication_pool_handle() {
if let Some(pool) = startup_runtime_sources::replication_pool_handle() {
pool.init_resync(ctx, buckets.clone()).await?;
}
+5 -1
View File
@@ -13,7 +13,7 @@
// limitations under the License.
use crate::config::RustFSBufferConfig;
use crate::storage::{set_global_region, set_global_rustfs_port};
use crate::storage::{DynReplicationPool, set_global_region, set_global_rustfs_port};
use rustfs_kms::KmsServiceManager;
use rustfs_obs::{GlobalError as ObservabilityError, OtelGuard};
use rustfs_tls_runtime::{OutboundTlsMaterial, TlsGeneration};
@@ -71,6 +71,10 @@ pub(crate) fn init_metrics_runtime(ctx: CancellationToken) {
rustfs_obs::init_metrics_runtime(ctx);
}
pub(crate) fn replication_pool_handle() -> Option<Arc<DynReplicationPool>> {
crate::app::context::resolve_replication_pool_handle()
}
pub(crate) fn set_put_stage_metrics_enabled(enabled: bool) {
rustfs_io_metrics::set_put_stage_metrics_enabled(enabled);
}
+4 -4
View File
@@ -18,12 +18,12 @@ use super::resolve_object_store_handle;
use super::{
PolicySys, StorageError, get_bucket_metadata, get_bucket_policy_raw, get_public_access_block_config, is_err_bucket_not_found,
};
use crate::app::context::resolve_region;
use crate::auth::{check_key_valid, get_condition_values_with_query_and_client_info, get_session_token};
use crate::error::ApiError;
use crate::license::license_check;
use crate::server::RemoteAddr;
use crate::storage::request_context::RequestContext;
use crate::storage::runtime_sources;
use metrics::counter;
use rustfs_iam::error::Error as IamError;
use rustfs_policy::policy::action::{Action, AdminAction, S3Action};
@@ -328,7 +328,7 @@ pub async fn authorize_request<T>(req: &mut S3Request<T>, action: Action) -> S3R
let version_id = req_info.version_id.clone();
if let Some(cred) = &cred {
let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else {
let Ok(iam_store) = runtime_sources::ready_iam_handle() else {
return Err(S3Error::with_message(
S3ErrorCode::InternalError,
format!("authorize_request {:?}", IamError::IamSysNotInitialized),
@@ -841,7 +841,7 @@ async fn authorize_table_data_plane_if_needed(
let Some(resource) = table_data_plane_resource_for_request(bucket, object).await? else {
return Ok(());
};
let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else {
let Ok(iam_store) = runtime_sources::ready_iam_handle() else {
return Err(s3_error!(InternalError, "iam not init"));
};
@@ -931,7 +931,7 @@ impl S3Access for FS {
let req_info = ReqInfo {
cred,
is_owner,
region: resolve_region(),
region: runtime_sources::region(),
request_context,
..Default::default()
};
+3 -3
View File
@@ -19,7 +19,7 @@ use super::io_schedule::{
get_advanced_buffer_size,
};
use super::request_guard::{GetObjectGuard, PutObjectGuard};
use crate::app::context::resolve_performance_metrics;
use crate::storage::runtime_sources;
use rustfs_concurrency::{
AdmissionState, GetObjectQueueSnapshot, WorkloadAdmissionRegistrySnapshot, WorkloadAdmissionSnapshot,
WorkloadAdmissionSnapshotProvider, WorkloadClass,
@@ -118,7 +118,7 @@ impl ConcurrencyManager {
// Use global performance metrics instance for consistent metrics tracking
// This allows AutoTuner and other components to access the same metrics data
let performance_metrics = resolve_performance_metrics();
let performance_metrics = runtime_sources::performance_metrics();
// Initialize metrics collector for I/O latency tracking
// Keep 1000 samples for P95/P99 calculation
@@ -235,7 +235,7 @@ impl ConcurrencyManager {
///
/// Arc-wrapped PerformanceMetrics instance
pub fn performance_metrics(&self) -> Arc<PerformanceMetrics> {
resolve_performance_metrics()
runtime_sources::performance_metrics()
}
/// Calculate an adaptive I/O strategy based on disk permit wait time.
+24 -24
View File
@@ -22,13 +22,13 @@ use super::{
};
use super::{StorageReplicationConfigExt as _, StorageVersioningConfigExt as _};
use crate::app::bucket_usecase::DefaultBucketUsecase;
use crate::app::context::resolve_object_store_handle;
use crate::app::multipart_usecase::DefaultMultipartUsecase;
use crate::app::object_usecase::DefaultObjectUsecase;
use crate::error::ApiError;
use crate::storage::access::has_bypass_governance_header;
use crate::storage::helper::OperationHelper;
use crate::storage::options::get_opts;
use crate::storage::runtime_sources;
use crate::storage::s3_api::acl;
use crate::storage::{parse_object_lock_legal_hold, parse_object_lock_retention, validate_bucket_object_lock_enabled};
use crate::table_catalog;
@@ -97,7 +97,7 @@ impl FS {
object: &str,
version_id: Option<&str>,
) -> S3Result<std::collections::HashMap<String, Vec<String>>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Ok(std::collections::HashMap::new());
};
let opts = ObjectOptions {
@@ -341,7 +341,7 @@ impl S3 for FS {
&self,
req: S3Request<DeleteBucketWebsiteInput>,
) -> S3Result<S3Response<DeleteBucketWebsiteOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
@@ -390,7 +390,7 @@ impl S3 for FS {
validate_table_catalog_object_mutation(&bucket, &object).await?;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
error!(
component = LOG_COMPONENT_STORAGE,
subsystem = LOG_SUBSYSTEM_TAGGING,
@@ -472,7 +472,7 @@ impl S3 for FS {
record_s3_op(S3Operation::GetBucketAcl, &req.input.bucket);
let GetBucketAclInput { bucket, .. } = req.input;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -488,7 +488,7 @@ impl S3 for FS {
&self,
req: S3Request<GetBucketAccelerateConfigurationInput>,
) -> S3Result<S3Response<GetBucketAccelerateConfigurationOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
@@ -578,7 +578,7 @@ impl S3 for FS {
&self,
req: S3Request<GetBucketRequestPaymentInput>,
) -> S3Result<S3Response<GetBucketRequestPaymentOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
@@ -626,7 +626,7 @@ impl S3 for FS {
}
async fn get_bucket_website(&self, req: S3Request<GetBucketWebsiteInput>) -> S3Result<S3Response<GetBucketWebsiteOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
@@ -664,7 +664,7 @@ impl S3 for FS {
bucket, key, version_id, ..
} = req.input;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -694,7 +694,7 @@ impl S3 for FS {
bucket, key, version_id, ..
} = req.input.clone();
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -755,7 +755,7 @@ impl S3 for FS {
record_s3_op(S3Operation::GetObjectLockConfiguration, &req.input.bucket);
let GetObjectLockConfigurationInput { bucket, .. } = req.input;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -803,7 +803,7 @@ impl S3 for FS {
bucket, key, version_id, ..
} = req.input.clone();
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -855,7 +855,7 @@ impl S3 for FS {
let bucket = req.input.bucket.as_str();
let object = req.input.key.as_str();
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
error!(
component = LOG_COMPONENT_STORAGE,
subsystem = LOG_SUBSYSTEM_TAGGING,
@@ -1013,7 +1013,7 @@ impl S3 for FS {
} = req.input;
record_s3_op(S3Operation::PutBucketAcl, &bucket);
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -1036,7 +1036,7 @@ impl S3 for FS {
&self,
req: S3Request<PutBucketAccelerateConfigurationInput>,
) -> S3Result<S3Response<PutBucketAccelerateConfigurationOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
store
@@ -1061,7 +1061,7 @@ impl S3 for FS {
async fn get_bucket_logging(&self, req: S3Request<GetBucketLoggingInput>) -> S3Result<S3Response<GetBucketLoggingOutput>> {
record_s3_op(S3Operation::GetBucketLogging, &req.input.bucket);
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
store
@@ -1080,7 +1080,7 @@ impl S3 for FS {
async fn put_bucket_logging(&self, req: S3Request<PutBucketLoggingInput>) -> S3Result<S3Response<PutBucketLoggingOutput>> {
record_s3_op(S3Operation::PutBucketLogging, &req.input.bucket);
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
store
@@ -1139,7 +1139,7 @@ impl S3 for FS {
&self,
req: S3Request<PutBucketRequestPaymentInput>,
) -> S3Result<S3Response<PutBucketRequestPaymentOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
store
@@ -1181,7 +1181,7 @@ impl S3 for FS {
}
async fn put_bucket_website(&self, req: S3Request<PutBucketWebsiteInput>) -> S3Result<S3Response<PutBucketWebsiteOutput>> {
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(s3_error!(InternalError, "Not init"));
};
store
@@ -1211,7 +1211,7 @@ impl S3 for FS {
let key = &req.input.key;
let version_id = req.input.version_id.clone();
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -1253,7 +1253,7 @@ impl S3 for FS {
validate_table_catalog_object_mutation(&bucket, &key).await?;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -1307,7 +1307,7 @@ impl S3 for FS {
let Some(input_cfg) = object_lock_configuration else { return Err(s3_error!(InvalidArgument)) };
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -1379,7 +1379,7 @@ impl S3 for FS {
validate_table_catalog_object_mutation(&bucket, &key).await?;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
@@ -1458,7 +1458,7 @@ impl S3 for FS {
crate::storage::s3_api::tagging::validate_object_tag_set(&tagging.tag_set)?;
let Some(store) = resolve_object_store_handle() else {
let Some(store) = runtime_sources::object_store_handle() else {
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
};
+2 -2
View File
@@ -17,7 +17,6 @@ use super::{
StorageError, add_object_lock_years, get_bucket_cors_config, get_bucket_object_lock_config, get_bucket_replication_config,
resolve_object_store_handle,
};
use crate::app::context::resolve_buffer_config;
use crate::config::{RustFSBufferConfig, WorkloadProfile, is_buffer_profile_enabled};
use crate::error::ApiError;
use crate::server::cors;
@@ -47,6 +46,7 @@ use time::format_description::well_known::Rfc3339;
use time::{format_description::FormatItem, macros::format_description};
use tracing::{debug, warn};
use crate::storage::runtime_sources;
use crate::storage::{StorageObjectInfo as ObjectInfo, StorageObjectToDelete as ObjectToDelete};
const LOG_COMPONENT_STORAGE: &str = "storage";
@@ -263,7 +263,7 @@ pub(crate) fn get_adaptive_buffer_size_with_profile(file_size: i64, profile: Opt
pub(crate) fn get_buffer_size_opt_in(file_size: i64) -> usize {
let buffer_size = if is_buffer_profile_enabled() {
// Use the AppContext-owned profile when available, with global fallback during migration.
let config = resolve_buffer_config();
let config = runtime_sources::buffer_config();
config.get_buffer_size(file_size)
} else {
// Opt-out mode: Use GeneralPurpose profile for consistent behavior
+3 -3
View File
@@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context::{resolve_action_credentials, resolve_notify_interface};
use crate::server::{convert_ecstore_object_info, is_audit_module_enabled, is_notify_module_enabled};
use crate::storage::access::{ReqInfo, request_context_from_req};
use crate::storage::request_context::{RequestContext, extract_request_id_from_headers};
use crate::storage::runtime_sources;
use hashbrown::HashMap;
use http::StatusCode;
use metrics::counter;
@@ -312,7 +312,7 @@ impl OperationHelper {
final_builder = final_builder.error(err);
}
if let Some(cred) = resolve_action_credentials() {
if let Some(cred) = runtime_sources::action_credentials() {
final_builder = final_builder.access_key(&cred.access_key);
}
@@ -383,7 +383,7 @@ impl Drop for OperationHelper {
if !event_args.is_replication_request() {
let ctx = state.request_context.clone();
spawn_background_with_context(ctx, async move {
resolve_notify_interface().notify(event_args).await;
runtime_sources::notify_interface().notify(event_args).await;
});
}
}
+1
View File
@@ -44,6 +44,7 @@ mod ecfs_test;
pub(crate) mod head_prefix;
#[cfg(test)]
mod multi_factor_scheduler_integration_test;
pub(crate) mod runtime_sources;
#[cfg(test)]
mod sse_test;
+3 -3
View File
@@ -13,7 +13,7 @@
// limitations under the License.
use super::*;
use crate::app::context::resolve_internode_metrics;
use crate::storage::runtime_sources;
use rustfs_io_metrics::internode_metrics::{
INTERNODE_OPERATION_GRPC_READ_ALL, INTERNODE_OPERATION_GRPC_WRITE_ALL, INTERNODE_TRANSPORT_BACKEND_GRPC,
};
@@ -934,7 +934,7 @@ impl NodeService {
pub(super) async fn handle_write_all(&self, request: Request<WriteAllRequest>) -> Result<Response<WriteAllResponse>, Status> {
let request = request.into_inner();
let data_len = request.data.len();
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
metrics.record_incoming_request_for_operation_and_backend(
INTERNODE_OPERATION_GRPC_WRITE_ALL,
INTERNODE_TRANSPORT_BACKEND_GRPC,
@@ -974,7 +974,7 @@ impl NodeService {
debug!("read all");
let request = request.into_inner();
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
metrics.record_incoming_request_for_operation_and_backend(
INTERNODE_OPERATION_GRPC_READ_ALL,
INTERNODE_TRANSPORT_BACKEND_GRPC,
+7 -7
View File
@@ -13,8 +13,8 @@
// limitations under the License.
use super::*;
use crate::app::context::resolve_local_node_name;
use crate::storage::rpc::encode_msgpack_map;
use crate::storage::runtime_sources;
use rustfs_storage_api::StorageAdminApi;
impl NodeService {
@@ -22,7 +22,7 @@ impl NodeService {
&self,
_request: Request<GetProcInfoRequest>,
) -> Result<Response<GetProcInfoResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_proc_info(&addr);
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetProcInfoResponse {
@@ -42,7 +42,7 @@ impl NodeService {
&self,
_request: Request<GetMemInfoRequest>,
) -> Result<Response<GetMemInfoResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_mem_info(&addr);
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetMemInfoResponse {
@@ -62,7 +62,7 @@ impl NodeService {
&self,
_request: Request<GetSysErrorsRequest>,
) -> Result<Response<GetSysErrorsResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_sys_errors(&addr);
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetSysErrorsResponse {
@@ -82,7 +82,7 @@ impl NodeService {
&self,
_request: Request<GetSysConfigRequest>,
) -> Result<Response<GetSysConfigResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_sys_config(&addr);
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetSysConfigResponse {
@@ -102,7 +102,7 @@ impl NodeService {
&self,
_request: Request<GetSeLinuxInfoRequest>,
) -> Result<Response<GetSeLinuxInfoResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_sys_services(&addr);
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetSeLinuxInfoResponse {
@@ -160,7 +160,7 @@ impl NodeService {
&self,
_request: Request<GetNetInfoRequest>,
) -> Result<Response<GetNetInfoResponse>, Status> {
let addr = resolve_local_node_name().await;
let addr = runtime_sources::local_node_name().await;
let info = get_net_info(&addr, "");
match encode_msgpack_map(&info) {
Ok(buf) => Ok(Response::new(GetNetInfoResponse {
+8 -8
View File
@@ -17,9 +17,9 @@ use super::super::StorageDiskRpcExt as _;
use super::super::WalkDirOptions;
use super::super::find_local_disk_by_ref;
use super::super::verify_rpc_signature;
use crate::app::context::resolve_internode_metrics;
use crate::server::RPC_PREFIX;
use crate::storage::request_context::spawn_traced;
use crate::storage::runtime_sources;
use bytes::{Bytes, BytesMut};
use futures_util::TryStreamExt;
use http::{HeaderMap, Method, Request, Response, StatusCode, Uri};
@@ -302,7 +302,7 @@ async fn handle_internode_rpc(req: Request<Incoming>) -> Response<Body> {
}
if let Some(operation) = operation {
resolve_internode_metrics().record_duration_for_operation_and_backend(
runtime_sources::internode_metrics().record_duration_for_operation_and_backend(
operation,
INTERNODE_TRANSPORT_BACKEND_TCP_HTTP,
started_at.elapsed(),
@@ -322,7 +322,7 @@ fn internode_http_operation(path: &str) -> Option<&'static str> {
}
fn record_internode_rpc_error(operation: Option<&'static str>) {
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
match operation {
Some(operation) => metrics.record_error_for_operation_and_backend(operation, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP),
None => metrics.record_error(),
@@ -410,7 +410,7 @@ async fn handle_read_file(req: Request<Incoming>) -> Response<Body> {
}
};
resolve_internode_metrics().record_incoming_request_for_operation_and_backend(
runtime_sources::internode_metrics().record_incoming_request_for_operation_and_backend(
INTERNODE_OPERATION_READ_FILE_STREAM,
INTERNODE_TRANSPORT_BACKEND_TCP_HTTP,
);
@@ -430,7 +430,7 @@ fn read_file_body_stream<R>(
where
R: tokio::io::AsyncRead + Unpin + Send + Sync + 'static,
{
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
let stream = ReaderStream::with_capacity(reader, DEFAULT_READ_BUFFER_SIZE).map_ok(move |bytes| {
metrics.record_sent_bytes_for_operation_and_backend(operation, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP, bytes.len());
bytes
@@ -545,9 +545,9 @@ async fn handle_walk_dir(req: Request<Incoming>) -> Response<Body> {
}
});
resolve_internode_metrics()
runtime_sources::internode_metrics()
.record_incoming_request_for_operation_and_backend(INTERNODE_OPERATION_WALK_DIR, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP);
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
let stream = ReaderStream::with_capacity(rd, DEFAULT_READ_BUFFER_SIZE).map_ok(move |bytes| {
metrics.record_sent_bytes_for_operation_and_backend(
INTERNODE_OPERATION_WALK_DIR,
@@ -614,7 +614,7 @@ async fn handle_put_file(req: Request<Incoming>) -> Response<Body> {
}
};
let metrics = resolve_internode_metrics();
let metrics = runtime_sources::internode_metrics();
metrics.record_incoming_request_for_operation_and_backend(
INTERNODE_OPERATION_PUT_FILE_STREAM,
INTERNODE_TRANSPORT_BACKEND_TCP_HTTP,
+62
View File
@@ -0,0 +1,62 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::app::context;
use crate::config::RustFSBufferConfig;
use crate::storage::ECStore;
use rustfs_credentials::Credentials;
use rustfs_iam::{error::Result as IamResult, store::object::ObjectStore, sys::IamSys};
use rustfs_io_metrics::{PerformanceMetrics, internode_metrics::InternodeMetrics};
use rustfs_kms::ObjectEncryptionService;
use std::sync::Arc;
pub(crate) fn object_store_handle() -> Option<Arc<ECStore>> {
context::resolve_object_store_handle()
}
pub(crate) fn buffer_config() -> RustFSBufferConfig {
context::resolve_buffer_config()
}
pub(crate) fn internode_metrics() -> Arc<InternodeMetrics> {
context::resolve_internode_metrics()
}
pub(crate) async fn local_node_name() -> String {
context::resolve_local_node_name().await
}
pub(crate) fn action_credentials() -> Option<Credentials> {
context::resolve_action_credentials()
}
pub(crate) fn notify_interface() -> Arc<dyn context::NotifyInterface> {
context::resolve_notify_interface()
}
pub(crate) fn performance_metrics() -> Arc<PerformanceMetrics> {
context::resolve_performance_metrics()
}
pub(crate) async fn encryption_service() -> Option<Arc<ObjectEncryptionService>> {
context::resolve_encryption_service().await
}
pub(crate) fn region() -> Option<s3s::region::Region> {
context::resolve_region()
}
pub(crate) fn ready_iam_handle() -> IamResult<Arc<IamSys<ObjectStore>>> {
context::resolve_ready_iam_handle()
}
+5 -5
View File
@@ -70,7 +70,7 @@
//! ```
use super::StorageError;
use crate::app::context::resolve_encryption_service;
use crate::storage::runtime_sources;
#[cfg(feature = "rio-v2")]
use aes_gcm::aead::Payload;
use aes_gcm::{
@@ -1533,7 +1533,7 @@ async fn apply_managed_encryption_material(
let mut kms_key_candidate = kms_key_id.clone();
if kms_key_candidate.is_none() {
// Try to get default key from KMS service (if available)
if let Some(service) = resolve_encryption_service().await {
if let Some(service) = runtime_sources::encryption_service().await {
kms_key_candidate = service.get_default_key_id().cloned();
}
}
@@ -1626,7 +1626,7 @@ async fn apply_managed_decryption_material(
.cloned()
.unwrap_or_else(|| "AES256".to_string()),
)
} else if let Some(service) = resolve_encryption_service().await {
} else if let Some(service) = runtime_sources::encryption_service().await {
// Production mode: use service for metadata parsing
let parsed = service
.headers_to_metadata(&normalized_metadata)
@@ -1804,7 +1804,7 @@ impl KmsSseDekProvider {
}
async fn current_service() -> Option<Arc<rustfs_kms::service::ObjectEncryptionService>> {
resolve_encryption_service().await
runtime_sources::encryption_service().await
}
}
@@ -2082,7 +2082,7 @@ static GLOBAL_SSE_DEK_PROVIDER: LazyLock<RwLock<Option<Arc<dyn SseDekProvider>>>
/// .await?;
/// ```
pub async fn get_sse_dek_provider() -> Result<Arc<dyn SseDekProvider>, ApiError> {
if resolve_encryption_service().await.is_some() {
if runtime_sources::encryption_service().await.is_some() {
debug!("Using KmsSseDekProvider (KMS configured)");
return Ok(Arc::new(KmsSseDekProvider::new().await?));
}
@@ -154,6 +154,8 @@ RUSTFS_WORKLOAD_DIRECT_FOREGROUND_MAPPING_HITS_FILE="${TMP_DIR}/rustfs_workload_
IAM_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/iam_runtime_source_bypass_hits.txt"
RUSTFS_APP_CONTEXT_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_app_context_runtime_source_bypass_hits.txt"
RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_startup_runtime_source_bypass_hits.txt"
RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_server_runtime_source_bypass_hits.txt"
RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_storage_runtime_source_bypass_hits.txt"
awk '
/^## PR Types$/ {
@@ -1336,6 +1338,40 @@ if [[ -s "$RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then
report_failure "RustFS startup runtime globals must stay behind rustfs/src/startup_runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'crate::app::context::(?:\{[^}]*\b(?:resolve_server_config|resolve_notify_interface|resolve_object_store_handle|resolve_kms_runtime_service_manager|resolve_iam_ready|resolve_endpoints_handle|resolve_lock_clients_handle)\b|(?:resolve_server_config|resolve_notify_interface|resolve_object_store_handle|resolve_kms_runtime_service_manager|resolve_iam_ready|resolve_endpoints_handle|resolve_lock_clients_handle)\b)' \
rustfs/src/server/audit.rs \
rustfs/src/server/event.rs \
rustfs/src/server/layer.rs \
rustfs/src/server/module_switch.rs \
rustfs/src/server/readiness.rs \
--glob '*.rs' || true
) >"$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE"
if [[ -s "$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then
report_failure "RustFS server runtime source reads must stay behind rustfs/src/server/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'crate::app::context::(?:\{[^}]*\b(?:resolve_object_store_handle|resolve_buffer_config|resolve_internode_metrics|resolve_local_node_name|resolve_action_credentials|resolve_notify_interface|resolve_performance_metrics|resolve_encryption_service|resolve_region|resolve_ready_iam_handle)\b|(?:resolve_object_store_handle|resolve_buffer_config|resolve_internode_metrics|resolve_local_node_name|resolve_action_credentials|resolve_notify_interface|resolve_performance_metrics|resolve_encryption_service|resolve_region|resolve_ready_iam_handle)\b)' \
rustfs/src/storage/access.rs \
rustfs/src/storage/ecfs.rs \
rustfs/src/storage/ecfs_extend.rs \
rustfs/src/storage/helper.rs \
rustfs/src/storage/concurrency/manager.rs \
rustfs/src/storage/sse.rs \
rustfs/src/storage/rpc/disk.rs \
rustfs/src/storage/rpc/health.rs \
rustfs/src/storage/rpc/http_service.rs \
--glob '*.rs' || true
) >"$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE"
if [[ -s "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then
report_failure "RustFS storage runtime source reads must stay behind rustfs/src/storage/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'rustfs_ecstore::api::' \
+2 -19
View File
@@ -46,35 +46,18 @@ dep|rustfs/src/init.rs|infra->app|crate::app::context::resolve_region
dep|rustfs/src/init.rs|infra->interface|crate::admin
dep|rustfs/src/protocols/client.rs|infra->app|crate::app::context::resolve_action_credentials
dep|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::FS
dep|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config
dep|rustfs/src/server/module_switch.rs|infra->app|crate::app::context::resolve_object_store_handle
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_notify_interface
dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config
dep|rustfs/src/server/http.rs|infra->interface|crate::admin
dep|rustfs/src/server/layer.rs|infra->app|crate::app::context::resolve_kms_runtime_service_manager
dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::console::is_console_path
dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::HealthProbe
dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::build_health_response_parts
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_lock_clients_handle
dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_object_store_handle
dep|rustfs/src/startup_bucket_metadata.rs|infra->app|crate::app::context::resolve_replication_pool_handle
dep|rustfs/src/server/runtime_sources.rs|infra->app|crate::app::context
dep|rustfs/src/startup_iam.rs|infra->app|crate::app::context::AppContext
dep|rustfs/src/storage/ecfs_extend.rs|infra->app|crate::app::context::resolve_buffer_config
dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::FS
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::validate_object_lock_configuration_input
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_initiator
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_owner
dep|rustfs/src/storage/access.rs|infra->app|crate::app::context::resolve_region
dep|rustfs/src/storage/concurrency/manager.rs|infra->app|crate::app::context::resolve_performance_metrics
dep|rustfs/src/storage/sse.rs|infra->app|crate::app::context::resolve_encryption_service
dep|rustfs/src/storage/helper.rs|infra->app|crate::app::context::resolve_action_credentials
dep|rustfs/src/storage/helper.rs|infra->app|crate::app::context::resolve_notify_interface
dep|rustfs/src/storage/rpc/disk.rs|infra->app|crate::app::context::resolve_internode_metrics
dep|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name
dep|rustfs/src/storage/rpc/http_service.rs|infra->app|crate::app::context::resolve_internode_metrics
dep|rustfs/src/storage/runtime_sources.rs|infra->app|crate::app::context
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::AppContext
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::get_global_app_context
dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle