refactor(rustfs): move layer-neutral shared types out of server (#6060)

This commit is contained in:
Zhengchao An
2026-08-13 10:09:59 +08:00
committed by GitHub
parent 7e2eeb6fc3
commit 62c5d7bd44
14 changed files with 138 additions and 119 deletions
@@ -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]
+20 -20
View File
@@ -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,
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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};
+2 -3
View File
@@ -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;
+1
View File
@@ -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;
+3 -29
View File
@@ -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<Timestamp> {
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<NotifyEventArgs> {
let version_id = args.object.version_id.map(|v| v.to_string()).unwrap_or_default();
+1 -5
View File
@@ -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<tokio::sync::broadcast::Sender<()>>,
+1 -48
View File
@@ -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<ReadinessDegradedReason>,
}
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.
+102
View File
@@ -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<ReadinessDegradedReason>,
}
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<Timestamp> {
let nanosecond = value.nanosecond().try_into().ok()?;
Timestamp::new(value.unix_timestamp(), nanosecond).ok()
}
+1 -1
View File
@@ -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 _;
+2 -1
View File
@@ -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;
-8
View File
@@ -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