mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-05 21:07:43 +00:00
refactor: route admin replication stats through app context (#3779)
This commit is contained in:
@@ -5,14 +5,13 @@ 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-admin-site-replication-tls-context`
|
||||
- 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`.
|
||||
- Based on: API-163 local branch stacked on API-162 PR #3776.
|
||||
- Branch: `overtrue/arch-admin-replication-stats-context`
|
||||
- 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`.
|
||||
- Based on: API-164/API-165 local branch stacked on API-163 PR #3777.
|
||||
- PR type for this branch: `consumer-migration`
|
||||
- Runtime behavior changes: none.
|
||||
- Rust code changes: route admin site-replication and TLS debug outbound TLS
|
||||
generation/state reads through AppContext resolvers with legacy global
|
||||
fallback.
|
||||
- Rust code changes: route admin replication stats reads through AppContext
|
||||
resolvers with legacy global fallback.
|
||||
- CI/script changes: lock completed owner and test/fuzz boundaries against
|
||||
bare/glob imports, scattered raw ECStore facade subpaths, and startup
|
||||
runtime/root-server/table/S3/app shared/app bucket/app ECStore/admin facade
|
||||
@@ -21,7 +20,7 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
and storage owner thin bridge regressions, plus app context and notify
|
||||
event-bridge thin module regressions; accept the reviewed AppContext resolver
|
||||
reverse dependencies in the layer baseline.
|
||||
- Docs changes: record the 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 owner facade cleanup.
|
||||
- Docs changes: record the 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 owner facade cleanup.
|
||||
|
||||
## Phase 0 Tasks
|
||||
|
||||
@@ -4386,6 +4385,22 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
TLS global-read scan, Rust risk scan, branch freshness check, and
|
||||
three-expert review.
|
||||
|
||||
- [x] `API-166` Route admin replication stats reads through AppContext.
|
||||
- Do: add a replication stats AppContext interface and storage-owner wrapper,
|
||||
then route admin replication metrics, extended replication metrics, and
|
||||
site-replication metrics summary reads through the resolver.
|
||||
- Acceptance: admin production handlers no longer directly read
|
||||
`GLOBAL_REPLICATION_STATS`, while AppContext default adapters keep the
|
||||
existing global fallback.
|
||||
- Must preserve: replication metrics defaults when stats are absent, bucket
|
||||
latest-stat lookup, site-replication node metric mapping, bandwidth report
|
||||
enrichment, runtime-field enrichment, and existing storage owner global
|
||||
initialization.
|
||||
- Verification: RustFS compile coverage, targeted context resolver tests,
|
||||
migration guard, layer guard, formatting, diff hygiene, residual replication
|
||||
stats global-read scan, Rust risk scan, branch freshness check, and
|
||||
three-expert review.
|
||||
|
||||
## Next PRs
|
||||
|
||||
1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries.
|
||||
@@ -4437,6 +4452,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
| Quality/architecture | pass | API-165 keeps admin TLS debug outbound TLS status reads behind the AppContext resolver boundary. |
|
||||
| Migration preservation | pass | TLS debug status JSON fields, consumer labels, reload/env reporting, and legacy fallback behavior are preserved. |
|
||||
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration/layer guards, diff hygiene, residual TLS scan, and Rust risk scan passed for API-165. |
|
||||
| Quality/architecture | pass | API-166 keeps admin replication stats reads behind AppContext resolver boundaries with a storage-owner fallback wrapper. |
|
||||
| Migration preservation | pass | Admin replication metrics, site-replication summaries, bandwidth enrichment, and missing-stats defaults are preserved. |
|
||||
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration/layer guards, diff hygiene, residual stats scan, and Rust risk scan passed for API-166. |
|
||||
|
||||
## Verification Notes
|
||||
|
||||
@@ -4472,6 +4490,21 @@ Passed before push:
|
||||
- Rust risk scan: no new production unwrap/expect, panic/todo/unsafe, or cast
|
||||
risks added.
|
||||
|
||||
- Issue #660 API-166 current slice:
|
||||
- `cargo check --tests -p rustfs`: passed.
|
||||
- `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`:
|
||||
passed.
|
||||
- `cargo fmt --all`: passed.
|
||||
- `cargo fmt --all --check`: passed.
|
||||
- `git diff --check`: passed.
|
||||
- `bash -n scripts/check_architecture_migration_rules.sh`: passed.
|
||||
- `./scripts/check_architecture_migration_rules.sh`: passed.
|
||||
- `./scripts/check_layer_dependencies.sh`: passed.
|
||||
- AppContext replication stats resolver scan: passed; direct admin production
|
||||
`GLOBAL_REPLICATION_STATS` reads are removed.
|
||||
- Rust risk scan: no new production unwrap/expect, panic/todo/unsafe, or cast
|
||||
risks added.
|
||||
|
||||
- Issue #660 API-163 current slice:
|
||||
- `cargo check --tests -p rustfs`: passed.
|
||||
- `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`:
|
||||
|
||||
@@ -18,13 +18,12 @@ use super::super::metadata::BUCKET_TARGETS_FILE;
|
||||
use super::super::metadata_sys;
|
||||
use super::super::metadata_sys::get_replication_config;
|
||||
use super::super::replication::BucketStats;
|
||||
use super::super::replication::GLOBAL_REPLICATION_STATS;
|
||||
use super::super::target::BucketTarget;
|
||||
use crate::admin::auth::validate_admin_request;
|
||||
use crate::admin::handlers::site_replication::site_replication_peer_deployment_id_for_endpoint;
|
||||
use crate::admin::router::{AdminOperation, Operation, S3Router};
|
||||
use crate::admin::utils::read_compatible_admin_body;
|
||||
use crate::app::context::{resolve_object_store_handle, resolve_runtime_port};
|
||||
use crate::app::context::{resolve_object_store_handle, resolve_replication_stats_handle, resolve_runtime_port};
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::error::ApiError;
|
||||
use crate::server::{ADMIN_PREFIX, RemoteAddr};
|
||||
@@ -158,7 +157,7 @@ impl Operation for GetReplicationMetricsHandler {
|
||||
// TODO cluster cache
|
||||
// In actual implementation, statistics would be obtained from cluster
|
||||
// This is simplified to get from local cache
|
||||
let bucket_stats = match GLOBAL_REPLICATION_STATS.get() {
|
||||
let bucket_stats = match resolve_replication_stats_handle() {
|
||||
Some(s) => s.get_latest_replication_stats(bucket).await,
|
||||
None => BucketStats::default(),
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ use super::super::metadata::{
|
||||
BUCKET_SSECONFIG, BUCKET_TAGGING_CONFIG, BUCKET_TARGETS_FILE, BUCKET_VERSIONING_CONFIG, OBJECT_LOCK_CONFIG,
|
||||
};
|
||||
use super::super::metadata_sys;
|
||||
use super::super::replication::{GLOBAL_REPLICATION_STATS, ResyncOpts};
|
||||
use super::super::replication::ResyncOpts;
|
||||
use super::super::target::{ARN, BucketTarget, BucketTargetType, BucketTargets, Credentials};
|
||||
use super::super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
use super::super::{delete_admin_config, read_admin_config, save_admin_config};
|
||||
@@ -34,7 +34,7 @@ use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin
|
||||
use crate::app::context::{
|
||||
resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, resolve_object_store_handle,
|
||||
resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_region, resolve_replication_pool_handle,
|
||||
resolve_runtime_port, resolve_server_config,
|
||||
resolve_replication_stats_handle, resolve_runtime_port, resolve_server_config,
|
||||
};
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::config::get_config_snapshot;
|
||||
@@ -1740,7 +1740,7 @@ fn filter_sr_info(mut info: SRInfo, opts: &SRStatusOptions) -> SRInfo {
|
||||
}
|
||||
|
||||
async fn build_metrics_summary(local_peer: &PeerInfo) -> SRMetricsSummary {
|
||||
let Some(stats) = GLOBAL_REPLICATION_STATS.get() else {
|
||||
let Some(stats) = resolve_replication_stats_handle() else {
|
||||
return SRMetricsSummary::default();
|
||||
};
|
||||
|
||||
|
||||
@@ -394,27 +394,14 @@ pub(crate) mod quota {
|
||||
}
|
||||
|
||||
pub(crate) mod replication {
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) type BucketReplicationResyncStatus = super::ecstore_bucket::replication::BucketReplicationResyncStatus;
|
||||
pub(crate) type BucketStats = super::ecstore_bucket::replication::BucketStats;
|
||||
pub(crate) type ObjectOpts = super::ecstore_bucket::replication::ObjectOpts;
|
||||
pub(crate) type ReplicationStats = super::ecstore_bucket::replication::ReplicationStats;
|
||||
pub(crate) type ResyncOpts = super::ecstore_bucket::replication::ResyncOpts;
|
||||
#[cfg(test)]
|
||||
pub(crate) type ResyncStatusType = super::ecstore_bucket::replication::ResyncStatusType;
|
||||
#[cfg(test)]
|
||||
pub(crate) type TargetReplicationResyncStatus = super::ecstore_bucket::replication::TargetReplicationResyncStatus;
|
||||
|
||||
pub(crate) struct GlobalReplicationStatsCompat;
|
||||
|
||||
pub(crate) static GLOBAL_REPLICATION_STATS: GlobalReplicationStatsCompat = GlobalReplicationStatsCompat;
|
||||
|
||||
impl GlobalReplicationStatsCompat {
|
||||
pub(crate) fn get(&self) -> Option<&'static Arc<ReplicationStats>> {
|
||||
super::ecstore_bucket::replication::GLOBAL_REPLICATION_STATS.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod target {
|
||||
|
||||
@@ -19,7 +19,7 @@ use super::bucket_target_sys::{BucketTargetSys, PutObjectOptions, RemoveObjectOp
|
||||
use super::metadata::BUCKET_TARGETS_FILE;
|
||||
use super::metadata_sys;
|
||||
use super::read_admin_config_without_migrate;
|
||||
use super::replication::{BucketReplicationResyncStatus, BucketStats, GLOBAL_REPLICATION_STATS, ObjectOpts, ResyncOpts};
|
||||
use super::replication::{BucketReplicationResyncStatus, BucketStats, ObjectOpts, ResyncOpts};
|
||||
use super::target::{BucketTarget, BucketTargetType, BucketTargets};
|
||||
use super::versioning_sys::BucketVersioningSys;
|
||||
use super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
@@ -27,7 +27,7 @@ use crate::admin::console::{is_console_path, make_console_server};
|
||||
use crate::admin::handlers::oidc::is_oidc_path;
|
||||
use crate::app::context::{
|
||||
resolve_bucket_monitor_handle, resolve_deployment_id, resolve_notification_system, resolve_object_store_handle,
|
||||
resolve_region, resolve_replication_pool_handle, resolve_server_config,
|
||||
resolve_region, resolve_replication_pool_handle, resolve_replication_stats_handle, resolve_server_config,
|
||||
};
|
||||
use crate::app::object_usecase::DefaultObjectUsecase;
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
@@ -1421,7 +1421,7 @@ async fn ensure_replication_config_exists(bucket: &str) -> S3Result<()> {
|
||||
}
|
||||
|
||||
async fn build_replication_metrics_response(bucket: &str, route: ReplicationExtRoute) -> S3Result<S3Response<Body>> {
|
||||
let bucket_stats = match GLOBAL_REPLICATION_STATS.get() {
|
||||
let bucket_stats = match resolve_replication_stats_handle() {
|
||||
Some(stats) => stats.get_latest_replication_stats(bucket).await,
|
||||
None => BucketStats::default(),
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ use super::EndpointServerPools;
|
||||
use super::TierConfigMgr;
|
||||
use super::metadata_sys::BucketMetadataSys;
|
||||
use super::new_object_layer_fn;
|
||||
use super::{BucketBandwidthMonitor, DynReplicationPool, NotificationSys};
|
||||
use super::{BucketBandwidthMonitor, DynReplicationPool, NotificationSys, ReplicationStats};
|
||||
use crate::config::RustFSBufferConfig;
|
||||
use rustfs_config::server_config::Config;
|
||||
use rustfs_credentials::Credentials;
|
||||
@@ -111,6 +111,11 @@ pub fn resolve_replication_pool_handle() -> Option<Arc<DynReplicationPool>> {
|
||||
resolve_replication_pool_handle_with(get_global_app_context(), || default_replication_pool_interface().handle())
|
||||
}
|
||||
|
||||
/// Resolve replication statistics handle using AppContext-first precedence.
|
||||
pub fn resolve_replication_stats_handle() -> Option<Arc<ReplicationStats>> {
|
||||
resolve_replication_stats_handle_with(get_global_app_context(), || default_replication_stats_interface().handle())
|
||||
}
|
||||
|
||||
/// Resolve deployment identity using AppContext-first precedence.
|
||||
pub fn resolve_deployment_id() -> Option<String> {
|
||||
resolve_deployment_id_with(get_global_app_context(), || default_deployment_id_interface().get())
|
||||
@@ -227,6 +232,15 @@ fn resolve_replication_pool_handle_with(
|
||||
.or_else(fallback)
|
||||
}
|
||||
|
||||
fn resolve_replication_stats_handle_with(
|
||||
context: Option<Arc<AppContext>>,
|
||||
fallback: impl FnOnce() -> Option<Arc<ReplicationStats>>,
|
||||
) -> Option<Arc<ReplicationStats>> {
|
||||
context
|
||||
.and_then(|context| context.replication_stats().handle())
|
||||
.or_else(fallback)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn resolve_object_store_handle_with(
|
||||
context: Option<Arc<AppContext>>,
|
||||
@@ -318,7 +332,8 @@ mod tests {
|
||||
use crate::app::context::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
|
||||
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface,
|
||||
OutboundTlsRuntimeInterface, RegionInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
OutboundTlsRuntimeInterface, RegionInterface, ReplicationStatsInterface, RuntimePortInterface, ServerConfigInterface,
|
||||
TierConfigInterface,
|
||||
};
|
||||
use crate::config::{RustFSBufferConfig, WorkloadProfile};
|
||||
use async_trait::async_trait;
|
||||
@@ -387,6 +402,16 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
struct TestReplicationStatsInterface {
|
||||
stats: Option<Arc<ReplicationStats>>,
|
||||
}
|
||||
|
||||
impl ReplicationStatsInterface for TestReplicationStatsInterface {
|
||||
fn handle(&self) -> Option<Arc<ReplicationStats>> {
|
||||
self.stats.clone()
|
||||
}
|
||||
}
|
||||
|
||||
struct TestEndpointsInterface {
|
||||
endpoints: Option<EndpointServerPools>,
|
||||
}
|
||||
@@ -544,6 +569,8 @@ mod tests {
|
||||
let context_kms = Arc::new(KmsServiceManager::new());
|
||||
let fallback_kms = Arc::new(KmsServiceManager::new());
|
||||
let bucket_metadata = Arc::new(RwLock::new(BucketMetadataSys::new(object_store.clone())));
|
||||
let context_replication_stats = Arc::new(ReplicationStats::new());
|
||||
let fallback_replication_stats = Arc::new(ReplicationStats::new());
|
||||
let tier_config = TierConfigMgr::new();
|
||||
let server_config = Config::new();
|
||||
let buffer_config = RustFSBufferConfig::new(WorkloadProfile::AiTraining);
|
||||
@@ -591,6 +618,9 @@ mod tests {
|
||||
}),
|
||||
bucket_monitor: default_bucket_monitor_interface(),
|
||||
replication_pool: default_replication_pool_interface(),
|
||||
replication_stats: Arc::new(TestReplicationStatsInterface {
|
||||
stats: Some(context_replication_stats.clone()),
|
||||
}),
|
||||
endpoints: Arc::new(TestEndpointsInterface {
|
||||
endpoints: Some(endpoints.clone()),
|
||||
}),
|
||||
@@ -644,6 +674,10 @@ mod tests {
|
||||
&resolve_object_store_handle_with(Some(context.clone()), || None).expect("context object store"),
|
||||
&object_store
|
||||
));
|
||||
assert!(Arc::ptr_eq(
|
||||
&resolve_replication_stats_handle_with(Some(context.clone()), || None).expect("context replication stats"),
|
||||
&context_replication_stats
|
||||
));
|
||||
assert_eq!(
|
||||
resolve_endpoints_handle_with(Some(context.clone()), || None)
|
||||
.expect("context endpoints")
|
||||
@@ -706,6 +740,11 @@ mod tests {
|
||||
&resolve_object_store_handle_with(None, || Some(object_store.clone())).expect("fallback object store"),
|
||||
&object_store
|
||||
));
|
||||
assert!(Arc::ptr_eq(
|
||||
&resolve_replication_stats_handle_with(None, || Some(fallback_replication_stats.clone()))
|
||||
.expect("fallback replication stats"),
|
||||
&fallback_replication_stats
|
||||
));
|
||||
assert_eq!(
|
||||
resolve_endpoints_handle_with(None, || Some(endpoints.clone()))
|
||||
.expect("fallback endpoints")
|
||||
|
||||
@@ -18,14 +18,14 @@ use super::handles::{
|
||||
default_bucket_monitor_interface, default_buffer_config_interface, default_deployment_id_interface,
|
||||
default_endpoints_interface, default_kms_runtime_interface, default_local_node_name_interface, default_lock_client_interface,
|
||||
default_notification_system_interface, default_notify_interface, default_outbound_tls_runtime_interface,
|
||||
default_region_interface, default_replication_pool_interface, default_runtime_port_interface,
|
||||
default_server_config_interface, default_tier_config_interface,
|
||||
default_region_interface, default_replication_pool_interface, default_replication_stats_interface,
|
||||
default_runtime_port_interface, default_server_config_interface, default_tier_config_interface,
|
||||
};
|
||||
use super::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BucketMonitorInterface, BufferConfigInterface, DeploymentIdInterface,
|
||||
EndpointsInterface, IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface,
|
||||
NotificationSystemInterface, NotifyInterface, OutboundTlsRuntimeInterface, RegionInterface, ReplicationPoolInterface,
|
||||
RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
ReplicationStatsInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
};
|
||||
use rustfs_iam::{store::object::ObjectStore, sys::IamSys};
|
||||
use rustfs_kms::KmsServiceManager;
|
||||
@@ -45,6 +45,7 @@ pub struct AppContext {
|
||||
bucket_metadata: Arc<dyn BucketMetadataInterface>,
|
||||
bucket_monitor: Arc<dyn BucketMonitorInterface>,
|
||||
replication_pool: Arc<dyn ReplicationPoolInterface>,
|
||||
replication_stats: Arc<dyn ReplicationStatsInterface>,
|
||||
endpoints: Arc<dyn EndpointsInterface>,
|
||||
deployment_id: Arc<dyn DeploymentIdInterface>,
|
||||
runtime_port: Arc<dyn RuntimePortInterface>,
|
||||
@@ -70,6 +71,7 @@ impl AppContext {
|
||||
bucket_metadata: default_bucket_metadata_interface(),
|
||||
bucket_monitor: default_bucket_monitor_interface(),
|
||||
replication_pool: default_replication_pool_interface(),
|
||||
replication_stats: default_replication_stats_interface(),
|
||||
endpoints: default_endpoints_interface(),
|
||||
deployment_id: default_deployment_id_interface(),
|
||||
runtime_port: default_runtime_port_interface(),
|
||||
@@ -132,6 +134,10 @@ impl AppContext {
|
||||
self.replication_pool.clone()
|
||||
}
|
||||
|
||||
pub fn replication_stats(&self) -> Arc<dyn ReplicationStatsInterface> {
|
||||
self.replication_stats.clone()
|
||||
}
|
||||
|
||||
pub fn endpoints(&self) -> Arc<dyn EndpointsInterface> {
|
||||
self.endpoints.clone()
|
||||
}
|
||||
@@ -184,6 +190,7 @@ pub(super) struct AppContextTestInterfaces {
|
||||
pub(super) bucket_metadata: Arc<dyn BucketMetadataInterface>,
|
||||
pub(super) bucket_monitor: Arc<dyn BucketMonitorInterface>,
|
||||
pub(super) replication_pool: Arc<dyn ReplicationPoolInterface>,
|
||||
pub(super) replication_stats: Arc<dyn ReplicationStatsInterface>,
|
||||
pub(super) endpoints: Arc<dyn EndpointsInterface>,
|
||||
pub(super) deployment_id: Arc<dyn DeploymentIdInterface>,
|
||||
pub(super) runtime_port: Arc<dyn RuntimePortInterface>,
|
||||
@@ -210,6 +217,7 @@ impl AppContext {
|
||||
bucket_metadata: interfaces.bucket_metadata,
|
||||
bucket_monitor: interfaces.bucket_monitor,
|
||||
replication_pool: interfaces.replication_pool,
|
||||
replication_stats: interfaces.replication_stats,
|
||||
endpoints: interfaces.endpoints,
|
||||
deployment_id: interfaces.deployment_id,
|
||||
runtime_port: interfaces.runtime_port,
|
||||
|
||||
@@ -17,13 +17,14 @@ use super::super::TierConfigMgr;
|
||||
use super::super::metadata_sys::{BucketMetadataSys, get_global_bucket_metadata_sys};
|
||||
use super::super::{
|
||||
get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, get_global_lock_client,
|
||||
get_global_notification_sys, get_global_region, get_global_replication_pool, get_global_tier_config_mgr, global_rustfs_port,
|
||||
get_global_notification_sys, get_global_region, get_global_replication_pool, get_global_replication_stats,
|
||||
get_global_tier_config_mgr, global_rustfs_port,
|
||||
};
|
||||
use super::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BucketMonitorInterface, BufferConfigInterface, DeploymentIdInterface,
|
||||
EndpointsInterface, IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface,
|
||||
NotificationSystemInterface, NotifyInterface, OutboundTlsRuntimeInterface, RegionInterface, ReplicationPoolInterface,
|
||||
RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
ReplicationStatsInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
};
|
||||
use crate::config::{RustFSBufferConfig, get_global_buffer_config};
|
||||
use async_trait::async_trait;
|
||||
@@ -171,6 +172,16 @@ impl ReplicationPoolInterface for ReplicationPoolHandle {
|
||||
}
|
||||
}
|
||||
|
||||
/// Default replication statistics interface adapter.
|
||||
#[derive(Default)]
|
||||
pub struct ReplicationStatsHandle;
|
||||
|
||||
impl ReplicationStatsInterface for ReplicationStatsHandle {
|
||||
fn handle(&self) -> Option<Arc<super::super::ReplicationStats>> {
|
||||
get_global_replication_stats()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default endpoints interface adapter.
|
||||
#[derive(Default)]
|
||||
pub struct EndpointsHandle;
|
||||
@@ -300,6 +311,10 @@ pub fn default_replication_pool_interface() -> Arc<dyn ReplicationPoolInterface>
|
||||
Arc::new(ReplicationPoolHandle)
|
||||
}
|
||||
|
||||
pub fn default_replication_stats_interface() -> Arc<dyn ReplicationStatsInterface> {
|
||||
Arc::new(ReplicationStatsHandle)
|
||||
}
|
||||
|
||||
pub fn default_endpoints_interface() -> Arc<dyn EndpointsInterface> {
|
||||
Arc::new(EndpointsHandle)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
use super::super::EndpointServerPools;
|
||||
use super::super::TierConfigMgr;
|
||||
use super::super::metadata_sys::BucketMetadataSys;
|
||||
use super::super::{BucketBandwidthMonitor, DynReplicationPool, NotificationSys};
|
||||
use super::super::{BucketBandwidthMonitor, DynReplicationPool, NotificationSys, ReplicationStats};
|
||||
use crate::config::RustFSBufferConfig;
|
||||
use async_trait::async_trait;
|
||||
use rustfs_config::server_config::Config;
|
||||
@@ -89,6 +89,11 @@ pub trait ReplicationPoolInterface: Send + Sync {
|
||||
fn handle(&self) -> Option<Arc<DynReplicationPool>>;
|
||||
}
|
||||
|
||||
/// Replication statistics interface for admin metrics integration.
|
||||
pub trait ReplicationStatsInterface: Send + Sync {
|
||||
fn handle(&self) -> Option<Arc<ReplicationStats>>;
|
||||
}
|
||||
|
||||
/// Endpoints interface for application-layer use-cases.
|
||||
pub trait EndpointsInterface: Send + Sync {
|
||||
fn handle(&self) -> Option<EndpointServerPools>;
|
||||
|
||||
@@ -672,6 +672,12 @@ pub(crate) fn get_global_replication_pool() -> Option<Arc<DynReplicationPool>> {
|
||||
crate::storage::get_global_replication_pool()
|
||||
}
|
||||
|
||||
pub(crate) type ReplicationStats = crate::storage::ReplicationStats;
|
||||
|
||||
pub(crate) fn get_global_replication_stats() -> Option<Arc<ReplicationStats>> {
|
||||
crate::storage::get_global_replication_stats()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn boxed_reader<R>(reader: R) -> DynReader
|
||||
where
|
||||
|
||||
@@ -246,6 +246,7 @@ pub(crate) type ReadMultipleReq = ecstore_disk::ReadMultipleReq;
|
||||
pub(crate) type ReadMultipleResp = ecstore_disk::ReadMultipleResp;
|
||||
pub(crate) type ReadOptions = ecstore_disk::ReadOptions;
|
||||
pub(crate) type RenameDataResp = ecstore_disk::RenameDataResp;
|
||||
pub(crate) type ReplicationStats = ecstore_bucket::replication::ReplicationStats;
|
||||
pub(crate) type SetupType = ecstore_layout::SetupType;
|
||||
pub(crate) type StorageError = ecstore_error::StorageError;
|
||||
pub(crate) type TierConfigMgr = ecstore_tier::TierConfigMgr;
|
||||
@@ -300,6 +301,10 @@ pub(crate) fn get_global_replication_pool() -> Option<Arc<DynReplicationPool>> {
|
||||
ecstore_bucket::replication::get_global_replication_pool()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_replication_stats() -> Option<Arc<ReplicationStats>> {
|
||||
ecstore_bucket::replication::GLOBAL_REPLICATION_STATS.get().cloned()
|
||||
}
|
||||
|
||||
pub(crate) async fn try_migrate_bucket_metadata(store: Arc<ECStore>) {
|
||||
ecstore_bucket::migration::try_migrate_bucket_metadata(store).await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user