From 62c5d7bd44f52332637136e04c83bd2a8e6b283d Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Thu, 13 Aug 2026 10:09:59 +0800 Subject: [PATCH] refactor(rustfs): move layer-neutral shared types out of server (#6060) --- rustfs/src/admin/handlers/cluster_snapshot.rs | 2 +- rustfs/src/admin/handlers/health.rs | 40 +++---- rustfs/src/app/admin_usecase.rs | 3 +- rustfs/src/app/bucket_usecase.rs | 2 +- rustfs/src/app/object_usecase.rs | 2 +- rustfs/src/cluster_snapshot.rs | 5 +- rustfs/src/lib.rs | 1 + rustfs/src/server/event.rs | 32 +----- rustfs/src/server/mod.rs | 6 +- rustfs/src/server/readiness.rs | 49 +-------- rustfs/src/shared_types.rs | 102 ++++++++++++++++++ rustfs/src/storage/access.rs | 2 +- rustfs/src/storage/helper.rs | 3 +- scripts/layer-dependency-baseline.txt | 8 -- 14 files changed, 138 insertions(+), 119 deletions(-) create mode 100644 rustfs/src/shared_types.rs diff --git a/rustfs/src/admin/handlers/cluster_snapshot.rs b/rustfs/src/admin/handlers/cluster_snapshot.rs index 76ad4da62..e321f76c3 100644 --- a/rustfs/src/admin/handlers/cluster_snapshot.rs +++ b/rustfs/src/admin/handlers/cluster_snapshot.rs @@ -928,7 +928,7 @@ mod tests { ClusterListingDiagnosticsSnapshot, ClusterReadOnlySnapshot, ClusterRuntimeReadinessState, ClusterRuntimeStatusSnapshot, ClusterUsageFreshnessSnapshot, }; - use crate::server::{DependencyReadiness, ReadinessDegradedReason}; + use crate::shared_types::{DependencyReadiness, ReadinessDegradedReason}; use rustfs_concurrency::{AdmissionState, WorkloadAdmissionRegistrySnapshot, WorkloadAdmissionSnapshot, WorkloadClass}; #[test] diff --git a/rustfs/src/admin/handlers/health.rs b/rustfs/src/admin/handlers/health.rs index 8efd5ba51..7a6715d67 100644 --- a/rustfs/src/admin/handlers/health.rs +++ b/rustfs/src/admin/handlers/health.rs @@ -195,14 +195,14 @@ mod tests { #[test] fn test_build_health_response_readiness_returns_503_when_deps_not_ready() { - let readiness_report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let readiness_report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: false, iam_ready: true, lock_quorum_ready: true, peer_health_ready: true, }, - degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageQuorumUnavailable], + degraded_reasons: vec![crate::shared_types::ReadinessDegradedReason::StorageQuorumUnavailable], }; let parts = build_health_response_parts( Method::GET, @@ -217,8 +217,8 @@ mod tests { #[test] fn test_build_health_response_readiness_returns_200_when_deps_ready() { - let readiness_report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let readiness_report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: true, iam_ready: true, lock_quorum_ready: true, @@ -239,14 +239,14 @@ mod tests { #[test] fn test_build_health_response_liveness_returns_200_when_deps_not_ready() { - let readiness_report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let readiness_report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: false, iam_ready: false, lock_quorum_ready: false, peer_health_ready: true, }, - degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageAndIamUnavailable], + degraded_reasons: vec![crate::shared_types::ReadinessDegradedReason::StorageAndIamUnavailable], }; let parts = build_health_response_parts( Method::GET, @@ -266,14 +266,14 @@ mod tests { #[test] fn test_build_health_response_head_returns_empty_body() { - let readiness_report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let readiness_report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: false, iam_ready: false, lock_quorum_ready: false, peer_health_ready: true, }, - degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageAndIamUnavailable], + degraded_reasons: vec![crate::shared_types::ReadinessDegradedReason::StorageAndIamUnavailable], }; let parts = build_health_response_parts( Method::HEAD, @@ -297,7 +297,7 @@ mod tests { storage_ready: true, iam_ready: false, lock_quorum_ready: true, - degraded_reasons: &[crate::server::ReadinessDegradedReason::IamNotReady], + degraded_reasons: &[crate::shared_types::ReadinessDegradedReason::IamNotReady], service: "rustfs-endpoint", uptime: Some(123), kms_ready: None, @@ -322,7 +322,7 @@ mod tests { storage_ready: false, iam_ready: false, lock_quorum_ready: false, - degraded_reasons: &[crate::server::ReadinessDegradedReason::StorageAndIamUnavailable], + degraded_reasons: &[crate::shared_types::ReadinessDegradedReason::StorageAndIamUnavailable], service: "rustfs-endpoint", uptime: None, kms_ready: None, @@ -334,8 +334,8 @@ mod tests { #[test] fn test_build_health_response_parts_head_has_no_payload() { - let report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: true, iam_ready: true, lock_quorum_ready: true, @@ -353,14 +353,14 @@ mod tests { #[serial] fn test_build_health_response_parts_get_includes_payload() { with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("false"), || { - let report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: false, iam_ready: true, lock_quorum_ready: true, peer_health_ready: true, }, - degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageQuorumUnavailable], + degraded_reasons: vec![crate::shared_types::ReadinessDegradedReason::StorageQuorumUnavailable], }; let parts = build_health_response_parts(Method::GET, HealthProbe::Readiness, Some(&report), "rustfs-endpoint", None, None); @@ -376,8 +376,8 @@ mod tests { #[serial] fn test_build_health_response_parts_readiness_marks_kms_not_ready() { with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("false"), || { - let report = crate::server::DependencyReadinessReport { - readiness: crate::server::DependencyReadiness { + let report = crate::shared_types::DependencyReadinessReport { + readiness: crate::shared_types::DependencyReadiness { storage_ready: true, iam_ready: true, lock_quorum_ready: true, diff --git a/rustfs/src/app/admin_usecase.rs b/rustfs/src/app/admin_usecase.rs index 7b0965074..877296f29 100644 --- a/rustfs/src/app/admin_usecase.rs +++ b/rustfs/src/app/admin_usecase.rs @@ -32,7 +32,8 @@ use crate::cluster_snapshot::{ collect_cluster_read_only_snapshot, }; use crate::error::ApiError; -use crate::server::{DependencyReadiness, collect_dependency_readiness_report as collect_runtime_dependency_readiness_report}; +use crate::server::collect_dependency_readiness_report as collect_runtime_dependency_readiness_report; +use crate::shared_types::DependencyReadiness; use rustfs_data_usage::DataUsageInfo; use rustfs_madmin::{InfoMessage, StorageInfo}; use s3s::S3ErrorCode; diff --git a/rustfs/src/app/bucket_usecase.rs b/rustfs/src/app/bucket_usecase.rs index ec8f07414..fdc711a17 100644 --- a/rustfs/src/app/bucket_usecase.rs +++ b/rustfs/src/app/bucket_usecase.rs @@ -74,7 +74,7 @@ use crate::app::runtime_sources::{ }; use crate::auth::get_condition_values_with_client_info; use crate::error::ApiError; -use crate::server::RemoteAddr; +use crate::shared_types::RemoteAddr; use crate::storage::storage_api::lock_bucket_targets_metadata; use http::StatusCode; use metrics::counter; diff --git a/rustfs/src/app/object_usecase.rs b/rustfs/src/app/object_usecase.rs index 8e420e97e..a922a3f15 100644 --- a/rustfs/src/app/object_usecase.rs +++ b/rustfs/src/app/object_usecase.rs @@ -113,7 +113,7 @@ use crate::app::runtime_sources::{ use crate::config::RustFSBufferConfig; use crate::delete_tail_activity::{DeleteTailActivityGuard, DeleteTailStage}; use crate::error::ApiError; -use crate::server::convert_ecstore_object_info; +use crate::shared_types::convert_ecstore_object_info; use crate::table_catalog; use bytes::{Bytes, BytesMut}; use futures::{Stream, StreamExt, TryStreamExt}; diff --git a/rustfs/src/cluster_snapshot.rs b/rustfs/src/cluster_snapshot.rs index ec2994526..8112afaf9 100644 --- a/rustfs/src/cluster_snapshot.rs +++ b/rustfs/src/cluster_snapshot.rs @@ -13,9 +13,8 @@ // limitations under the License. use crate::runtime_capabilities::runtime_observability_snapshot; -use crate::server::{ - DependencyReadiness, DependencyReadinessReport, ReadinessDegradedReason, snapshot_dependency_readiness_report, -}; +use crate::server::snapshot_dependency_readiness_report; +use crate::shared_types::{DependencyReadiness, DependencyReadinessReport, ReadinessDegradedReason}; use crate::storage_api::cluster::EndpointServerPools; use crate::storage_api::cluster::contract::observability::ObservabilitySnapshot; use crate::storage_api::cluster::contract::topology::TopologySnapshot; diff --git a/rustfs/src/lib.rs b/rustfs/src/lib.rs index 2a008cc24..077365569 100644 --- a/rustfs/src/lib.rs +++ b/rustfs/src/lib.rs @@ -94,6 +94,7 @@ pub mod protocols; pub mod runtime_capabilities; pub(crate) mod runtime_sources; pub mod server; +pub mod shared_types; pub(crate) mod site_replication_reconcile; pub(crate) mod startup_audit; pub(crate) mod startup_auth; diff --git a/rustfs/src/server/event.rs b/rustfs/src/server/event.rs index b406e6de2..b9ca8e6e5 100644 --- a/rustfs/src/server/event.rs +++ b/rustfs/src/server/event.rs @@ -18,13 +18,10 @@ use super::{ }; use crate::init::reconcile_persisted_bucket_notification_configurations; use crate::storage_api::server::event::{ - EventArgs as EcstoreEventArgs, StorageObjectInfo, read_existing_server_config_no_lock, register_event_dispatch_hook, + EventArgs as EcstoreEventArgs, read_existing_server_config_no_lock, register_event_dispatch_hook, with_server_config_read_lock, }; -use jiff::Timestamp; -use rustfs_notify::{ - EventArgs as NotifyEventArgs, NotificationError, NotificationRuntimeState, NotificationSystem, NotifyObjectInfo, -}; +use rustfs_notify::{EventArgs as NotifyEventArgs, NotificationError, NotificationRuntimeState, NotificationSystem}; use rustfs_s3_types::EventName; use std::future::Future; use std::net::SocketAddr; @@ -81,30 +78,7 @@ pub fn is_notify_module_enabled() -> bool { NOTIFY_MODULE_ENABLED.load(Ordering::Relaxed) } -pub(crate) fn convert_ecstore_object_info(object: StorageObjectInfo) -> NotifyObjectInfo { - NotifyObjectInfo { - bucket: object.bucket, - name: object.name, - size: object.size, - etag: object.etag, - content_type: object.content_type, - user_defined: object - .user_defined - .iter() - .map(|(key, value)| (key.clone(), value.clone())) - .collect(), - version_id: object.version_id.map(|version_id| version_id.to_string()), - mod_time: object.mod_time.and_then(offset_date_time_to_timestamp), - restore_expires: object.restore_expires.and_then(offset_date_time_to_timestamp), - storage_class: object.storage_class, - transitioned_tier: (!object.transitioned_object.tier.is_empty()).then_some(object.transitioned_object.tier), - } -} - -fn offset_date_time_to_timestamp(value: time::OffsetDateTime) -> Option { - let nanosecond = value.nanosecond().try_into().ok()?; - Timestamp::new(value.unix_timestamp(), nanosecond).ok() -} +pub(crate) use crate::shared_types::convert_ecstore_object_info; fn convert_ecstore_event_args(args: EcstoreEventArgs) -> Option { let version_id = args.object.version_id.map(|v| v.to_string()).unwrap_or_default(); diff --git a/rustfs/src/server/mod.rs b/rustfs/src/server/mod.rs index bcc00cdc4..22014e663 100644 --- a/rustfs/src/server/mod.rs +++ b/rustfs/src/server/mod.rs @@ -45,7 +45,6 @@ pub use service_state::ShutdownSignal; pub use service_state::wait_for_shutdown; // Items only used within the library crate (admin handlers, server/http.rs, etc.). -pub(crate) use event::convert_ecstore_object_info; pub(crate) use event::{ is_event_notifier_reconciled, mark_event_notifier_reconciled, mark_event_notifier_unreconciled, reconcile_event_notifier_from_store, start_persisted_event_notifier_reconciler, @@ -74,8 +73,6 @@ pub(crate) use prefix::{ PROFILE_MEMORY_PATH, RPC_PREFIX, RUSTFS_ADMIN_PREFIX, TABLE_CATALOG_COMPAT_PREFIX, TABLE_CATALOG_PREFIX, TONIC_PREFIX, VERSION, has_path_prefix, is_admin_path, is_table_catalog_path, }; -pub(crate) use readiness::DependencyReadiness; -pub(crate) use readiness::DependencyReadinessReport; pub(crate) use readiness::ReadinessDegradedReason; pub(crate) use readiness::ReadinessGateLayer; pub(crate) use readiness::collect_dependency_readiness_report; @@ -84,8 +81,7 @@ pub use readiness::publish_ready_when_runtime_ready; pub(crate) use readiness::snapshot_dependency_readiness_report; pub(crate) use readiness::{collect_cluster_read_health_report, collect_cluster_write_health_report}; -#[derive(Clone, Copy, Debug)] -pub struct RemoteAddr(pub std::net::SocketAddr); +pub use crate::shared_types::RemoteAddr; pub struct ShutdownHandle { shutdown_tx: Option>, diff --git a/rustfs/src/server/readiness.rs b/rustfs/src/server/readiness.rs index aa2697f67..d3954b7a7 100644 --- a/rustfs/src/server/readiness.rs +++ b/rustfs/src/server/readiness.rs @@ -74,54 +74,7 @@ fn startup_runtime_readiness_max_wait() -> Duration { const METRIC_RUNTIME_READINESS_READY: &str = "rustfs_runtime_readiness_ready"; const METRIC_RUNTIME_READINESS_DEGRADED_TOTAL: &str = "rustfs_runtime_readiness_degraded_total"; -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] -pub struct DependencyReadiness { - pub storage_ready: bool, - pub iam_ready: bool, - pub lock_quorum_ready: bool, - pub peer_health_ready: bool, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ReadinessDegradedReason { - StorageQuorumUnavailable, - IamNotReady, - LockQuorumUnavailable, - KmsNotReady, - ObjectReadStalled, - ObjectWriteStalled, - ClusterHealthTimeout, - PeerHealthUnavailable, - StorageAndIamUnavailable, - StorageAndLockUnavailable, - IamAndLockUnavailable, - StorageIamAndLockUnavailable, -} - -impl ReadinessDegradedReason { - pub fn as_str(&self) -> &'static str { - match self { - ReadinessDegradedReason::StorageQuorumUnavailable => "storage_quorum_unavailable", - ReadinessDegradedReason::IamNotReady => "iam_not_ready", - ReadinessDegradedReason::LockQuorumUnavailable => "lock_quorum_unavailable", - ReadinessDegradedReason::KmsNotReady => "kms_not_ready", - ReadinessDegradedReason::ObjectReadStalled => "object_read_stalled", - ReadinessDegradedReason::ObjectWriteStalled => "object_write_stalled", - ReadinessDegradedReason::ClusterHealthTimeout => "cluster_health_timeout", - ReadinessDegradedReason::PeerHealthUnavailable => "peer_health_unavailable", - ReadinessDegradedReason::StorageAndIamUnavailable => "storage_and_iam_unavailable", - ReadinessDegradedReason::StorageAndLockUnavailable => "storage_and_lock_unavailable", - ReadinessDegradedReason::IamAndLockUnavailable => "iam_and_lock_unavailable", - ReadinessDegradedReason::StorageIamAndLockUnavailable => "storage_iam_and_lock_unavailable", - } - } -} - -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct DependencyReadinessReport { - pub readiness: DependencyReadiness, - pub degraded_reasons: Vec, -} +pub use crate::shared_types::{DependencyReadiness, DependencyReadinessReport, ReadinessDegradedReason}; /// ReadinessGateLayer ensures that the system components (IAM, Storage) /// are fully initialized before allowing any request to proceed. diff --git a/rustfs/src/shared_types.rs b/rustfs/src/shared_types.rs new file mode 100644 index 000000000..2f351383b --- /dev/null +++ b/rustfs/src/shared_types.rs @@ -0,0 +1,102 @@ +// 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. + +//! Layer-neutral shared types (backlog#1834). +//! +//! These types are consumed across the app, infra, and interface layers but +//! used to live under `server`, so every lower-layer import was an upward +//! edge that had to be baselined by the layer-dependency guard. `server` +//! re-exports them for its own consumers; new code should import from here. + +use crate::storage_api::server::event::StorageObjectInfo; +use jiff::Timestamp; +use rustfs_notify::NotifyObjectInfo; + +/// Peer address of the current request, injected as a request extension. +#[derive(Clone, Copy, Debug)] +pub struct RemoteAddr(pub std::net::SocketAddr); + +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] +pub struct DependencyReadiness { + pub storage_ready: bool, + pub iam_ready: bool, + pub lock_quorum_ready: bool, + pub peer_health_ready: bool, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ReadinessDegradedReason { + StorageQuorumUnavailable, + IamNotReady, + LockQuorumUnavailable, + KmsNotReady, + ObjectReadStalled, + ObjectWriteStalled, + ClusterHealthTimeout, + PeerHealthUnavailable, + StorageAndIamUnavailable, + StorageAndLockUnavailable, + IamAndLockUnavailable, + StorageIamAndLockUnavailable, +} + +impl ReadinessDegradedReason { + pub fn as_str(&self) -> &'static str { + match self { + ReadinessDegradedReason::StorageQuorumUnavailable => "storage_quorum_unavailable", + ReadinessDegradedReason::IamNotReady => "iam_not_ready", + ReadinessDegradedReason::LockQuorumUnavailable => "lock_quorum_unavailable", + ReadinessDegradedReason::KmsNotReady => "kms_not_ready", + ReadinessDegradedReason::ObjectReadStalled => "object_read_stalled", + ReadinessDegradedReason::ObjectWriteStalled => "object_write_stalled", + ReadinessDegradedReason::ClusterHealthTimeout => "cluster_health_timeout", + ReadinessDegradedReason::PeerHealthUnavailable => "peer_health_unavailable", + ReadinessDegradedReason::StorageAndIamUnavailable => "storage_and_iam_unavailable", + ReadinessDegradedReason::StorageAndLockUnavailable => "storage_and_lock_unavailable", + ReadinessDegradedReason::IamAndLockUnavailable => "iam_and_lock_unavailable", + ReadinessDegradedReason::StorageIamAndLockUnavailable => "storage_iam_and_lock_unavailable", + } + } +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct DependencyReadinessReport { + pub readiness: DependencyReadiness, + pub degraded_reasons: Vec, +} + +pub(crate) fn convert_ecstore_object_info(object: StorageObjectInfo) -> NotifyObjectInfo { + NotifyObjectInfo { + bucket: object.bucket, + name: object.name, + size: object.size, + etag: object.etag, + content_type: object.content_type, + user_defined: object + .user_defined + .iter() + .map(|(key, value)| (key.clone(), value.clone())) + .collect(), + version_id: object.version_id.map(|version_id| version_id.to_string()), + mod_time: object.mod_time.and_then(offset_date_time_to_timestamp), + restore_expires: object.restore_expires.and_then(offset_date_time_to_timestamp), + storage_class: object.storage_class, + transitioned_tier: (!object.transitioned_object.tier.is_empty()).then_some(object.transitioned_object.tier), + } +} + +pub(crate) fn offset_date_time_to_timestamp(value: time::OffsetDateTime) -> Option { + let nanosecond = value.nanosecond().try_into().ok()?; + Timestamp::new(value.unix_timestamp(), nanosecond).ok() +} diff --git a/rustfs/src/storage/access.rs b/rustfs/src/storage/access.rs index bdab944e9..806035b70 100644 --- a/rustfs/src/storage/access.rs +++ b/rustfs/src/storage/access.rs @@ -21,7 +21,7 @@ use crate::auth::{ }; use crate::error::ApiError; use crate::license::license_check; -use crate::server::RemoteAddr; +use crate::shared_types::RemoteAddr; use crate::storage::request_context::RequestContext; use crate::storage::storage_api::contract::bucket::BUCKET_LIFECYCLE_LOCK_OBJECT; use crate::storage::storage_api::contract::namespace::NamespaceLocking as _; diff --git a/rustfs/src/storage/helper.rs b/rustfs/src/storage/helper.rs index 97f2cd06e..074d30f55 100644 --- a/rustfs/src/storage/helper.rs +++ b/rustfs/src/storage/helper.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::server::{convert_ecstore_object_info, is_audit_module_enabled, is_notify_module_enabled}; +use crate::server::{is_audit_module_enabled, is_notify_module_enabled}; +use crate::shared_types::convert_ecstore_object_info; use crate::storage::access::{ReqInfo, request_context_from_req}; use crate::storage::request_context::RequestContext; use crate::storage::sse::KmsRequestAuditScope; diff --git a/scripts/layer-dependency-baseline.txt b/scripts/layer-dependency-baseline.txt index 29f53f27d..e8540eed7 100644 --- a/scripts/layer-dependency-baseline.txt +++ b/scripts/layer-dependency-baseline.txt @@ -15,22 +15,14 @@ cycle|composition<->interface cycle|infra<->interface dep|rustfs/src/admin/handlers/scanner.rs|interface->composition|crate::startup_background::ENV_SCANNER_ENABLED dep|rustfs/src/admin/handlers/scanner.rs|interface->composition|crate::startup_background::scanner_enabled_from_env -dep|rustfs/src/app/admin_usecase.rs|app->interface|crate::server::DependencyReadiness dep|rustfs/src/app/admin_usecase.rs|app->interface|crate::server::collect_dependency_readiness_report dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_bucket_meta_hook dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_delete_bucket_hook dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_make_bucket_hook -dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::server::RemoteAddr -dep|rustfs/src/app/object_usecase.rs|app->interface|crate::server::convert_ecstore_object_info -dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::DependencyReadiness -dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::DependencyReadinessReport -dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::ReadinessDegradedReason dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::snapshot_dependency_readiness_report dep|rustfs/src/runtime_sources.rs|infra->app|crate::app::context -dep|rustfs/src/storage/access.rs|infra->interface|crate::server::RemoteAddr dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::server::cors dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery -dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::convert_ecstore_object_info dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::is_audit_module_enabled dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::is_notify_module_enabled dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::refresh_audit_module_enabled