mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-16 18:08:21 +00:00
refactor(rustfs): move module switches below the layer boundary
backlog#1834 PR5. Whether the scanner, heal, audit and notify modules are on gets read from infra (storage helpers, node-service RPC) and from interface (admin handlers), but the switches lived in startup_background (composition) and server (interface). Every one of those reads was an upward edge carried in the layer-dependency baseline. The env-derived scanner/heal predicates and the audit/notify state cells now live in rustfs/src/module_switches.rs, at the bottom of the layer order, so the same reads are ordinary downward edges. startup_background and server import from there; server keeps re-exporting the getters for its own consumers. The issue's plan was to move is/refresh_audit/notify_module_enabled as a group. Moving refresh_* wholesale would have dragged resolve_audit_module_state and resolve_notify_module_state — server-side configuration logic — down into infra, which breaks more layering than it fixes. State and resolution are split instead: module_switches owns the atomics plus is_*/set_* accessors, and server's refresh_* keeps the configuration logic and publishes through the setter. That leaves storage/helper.rs's test module importing refresh_* from server, so two infra->interface edges stay. Those tests assert that a configuration change takes effect through refresh, which a plain setter would no longer exercise; the edges are worth more than the two baseline lines. Baseline drops 44 -> 36 lines, deletions only: - 4 interface/infra -> composition edges for ENV_SCANNER_ENABLED, scanner_enabled_from_env and heal_enabled_from_env - 2 infra -> interface edges for is_audit_module_enabled and is_notify_module_enabled - cycle|composition<->infra and cycle|composition<->interface The two cycles were not expected to go until whole subsystems moved out; clearing composition's inbound upward edges dissolved both, leaving three of the original five. Verification: scripts/check_layer_dependencies.sh passes, cargo check -p rustfs warning-free, make pre-commit exit 0.
This commit is contained in:
@@ -16,8 +16,8 @@ use crate::admin::auth::validate_admin_request;
|
||||
use crate::admin::router::{AdminOperation, Operation, S3Router};
|
||||
use crate::admin::runtime_sources::current_scanner_metrics_report;
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::module_switches::{ENV_SCANNER_ENABLED, scanner_enabled_from_env};
|
||||
use crate::server::{ADMIN_PREFIX, RemoteAddr};
|
||||
use crate::startup_background::{ENV_SCANNER_ENABLED, scanner_enabled_from_env};
|
||||
use chrono::Utc;
|
||||
use http::{HeaderMap, HeaderValue};
|
||||
use hyper::{Method, StatusCode};
|
||||
|
||||
@@ -88,6 +88,7 @@ pub mod inspect;
|
||||
pub(crate) mod kms_deletion_gate;
|
||||
pub mod license;
|
||||
pub mod memory_observability;
|
||||
pub mod module_switches;
|
||||
pub mod profiling;
|
||||
#[cfg(any(feature = "ftps", feature = "webdav", feature = "sftp"))]
|
||||
pub mod protocols;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// 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 module switches (backlog#1834).
|
||||
//!
|
||||
//! Whether the scanner, heal, audit and notify modules are on is read from the
|
||||
//! infra layer (storage helpers, node-service RPC) and from the interface layer
|
||||
//! (admin handlers), but the switches used to live in `startup_background`
|
||||
//! (composition) and `server` (interface). Every lower-layer read was therefore
|
||||
//! an upward edge that had to be baselined by the layer-dependency guard.
|
||||
//!
|
||||
//! The env-derived scanner/heal predicates and the audit/notify state cells now
|
||||
//! live here, at the bottom of the layer order, so those reads are ordinary
|
||||
//! downward edges. Resolving the audit/notify state still needs server-side
|
||||
//! configuration, so `server::refresh_audit_module_enabled` and its notify twin
|
||||
//! keep that logic and publish the result through the setters below.
|
||||
|
||||
use rustfs_utils::get_env_bool_with_aliases;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub(crate) const ENV_SCANNER_ENABLED: &str = "RUSTFS_SCANNER_ENABLED";
|
||||
pub(crate) const ENV_SCANNER_ENABLED_DEPRECATED: &str = "RUSTFS_ENABLE_SCANNER";
|
||||
pub(crate) const ENV_HEAL_ENABLED: &str = "RUSTFS_HEAL_ENABLED";
|
||||
pub(crate) const ENV_HEAL_ENABLED_DEPRECATED: &str = "RUSTFS_ENABLE_HEAL";
|
||||
|
||||
static AUDIT_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_AUDIT_ENABLE);
|
||||
static NOTIFY_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_NOTIFY_ENABLE);
|
||||
|
||||
/// Whether the data scanner is enabled, defaulting to on.
|
||||
pub(crate) fn scanner_enabled_from_env() -> bool {
|
||||
get_env_bool_with_aliases(ENV_SCANNER_ENABLED, &[ENV_SCANNER_ENABLED_DEPRECATED], true)
|
||||
}
|
||||
|
||||
/// Whether background heal is enabled, defaulting to on.
|
||||
pub(crate) fn heal_enabled_from_env() -> bool {
|
||||
get_env_bool_with_aliases(ENV_HEAL_ENABLED, &[ENV_HEAL_ENABLED_DEPRECATED], true)
|
||||
}
|
||||
|
||||
/// Last published audit-module state.
|
||||
pub fn is_audit_module_enabled() -> bool {
|
||||
AUDIT_MODULE_ENABLED.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Publish the audit-module state resolved by `server::refresh_audit_module_enabled`.
|
||||
pub(crate) fn set_audit_module_enabled(enabled: bool) {
|
||||
AUDIT_MODULE_ENABLED.store(enabled, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Last published notify-module state.
|
||||
pub fn is_notify_module_enabled() -> bool {
|
||||
NOTIFY_MODULE_ENABLED.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Publish the notify-module state resolved by `server::refresh_notify_module_enabled`.
|
||||
pub(crate) fn set_notify_module_enabled(enabled: bool) {
|
||||
NOTIFY_MODULE_ENABLED.store(enabled, Ordering::Relaxed);
|
||||
}
|
||||
@@ -19,11 +19,8 @@ use super::{
|
||||
use crate::runtime_sources::AppContext;
|
||||
use rustfs_audit::{AuditError, AuditResult, audit_system, init_audit_system, system::AuditSystemState};
|
||||
use std::collections::HashSet;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
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> {
|
||||
runtime_sources::current_server_config()
|
||||
}
|
||||
@@ -37,13 +34,11 @@ fn server_config_for_context(context: Option<&AppContext>) -> Option<rustfs_conf
|
||||
|
||||
pub fn refresh_audit_module_enabled() -> bool {
|
||||
let enabled = resolve_audit_module_state().enabled;
|
||||
AUDIT_MODULE_ENABLED.store(enabled, Ordering::Relaxed);
|
||||
crate::module_switches::set_audit_module_enabled(enabled);
|
||||
enabled
|
||||
}
|
||||
|
||||
pub fn is_audit_module_enabled() -> bool {
|
||||
AUDIT_MODULE_ENABLED.load(Ordering::Relaxed)
|
||||
}
|
||||
pub use crate::module_switches::is_audit_module_enabled;
|
||||
|
||||
fn has_any_persisted_audit_targets(config: &rustfs_config::server_config::Config) -> bool {
|
||||
for &subsystem in rustfs_config::audit::AUDIT_SUB_SYSTEMS {
|
||||
|
||||
@@ -34,7 +34,6 @@ use tokio::time::{Instant, MissedTickBehavior};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{info, instrument, warn};
|
||||
|
||||
static NOTIFY_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_NOTIFY_ENABLE);
|
||||
static NOTIFY_RUNTIME_RECONCILED: AtomicBool = AtomicBool::new(false);
|
||||
static NOTIFY_BUCKET_RULES_RECONCILED: AtomicBool = AtomicBool::new(false);
|
||||
static ECSTORE_EVENT_DISPATCH_HOOK: OnceLock<()> = OnceLock::new();
|
||||
@@ -70,13 +69,11 @@ fn should_reconcile_bucket_notification_rules(runtime_changed: bool, notify_enab
|
||||
|
||||
pub fn refresh_notify_module_enabled() -> bool {
|
||||
let enabled = resolve_notify_module_state().enabled;
|
||||
NOTIFY_MODULE_ENABLED.store(enabled, Ordering::Relaxed);
|
||||
crate::module_switches::set_notify_module_enabled(enabled);
|
||||
enabled
|
||||
}
|
||||
|
||||
pub fn is_notify_module_enabled() -> bool {
|
||||
NOTIFY_MODULE_ENABLED.load(Ordering::Relaxed)
|
||||
}
|
||||
pub use crate::module_switches::is_notify_module_enabled;
|
||||
|
||||
pub(crate) use crate::shared_types::convert_ecstore_object_info;
|
||||
|
||||
@@ -171,7 +168,7 @@ pub(crate) async fn reconcile_event_notifier_from_store(
|
||||
let transition_system = system.clone();
|
||||
let transition_store = store.clone();
|
||||
let transition = with_refreshed_notify_module_state_from(store.clone(), move |resolution| async move {
|
||||
NOTIFY_MODULE_ENABLED.store(resolution.enabled, Ordering::Relaxed);
|
||||
crate::module_switches::set_notify_module_enabled(resolution.enabled);
|
||||
let read_store = transition_store.clone();
|
||||
let config_system = transition_system.clone();
|
||||
with_server_config_read_lock(transition_store, move || async move {
|
||||
|
||||
@@ -12,32 +12,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::module_switches::{heal_enabled_from_env, scanner_enabled_from_env};
|
||||
use crate::storage_api::startup::background::{ECStore, set_workload_admission_snapshot_provider};
|
||||
use crate::workload_admission::RustFsWorkloadAdmissionSnapshotProvider;
|
||||
use rustfs_concurrency::WorkloadAdmissionSnapshotProvider;
|
||||
use rustfs_heal::{
|
||||
create_ahm_services_cancel_token, heal::storage::ECStoreHealStorage, init_heal_manager_with_workload_provider,
|
||||
};
|
||||
use rustfs_utils::get_env_bool_with_aliases;
|
||||
use std::{io::Result, sync::Arc};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub(crate) const ENV_SCANNER_ENABLED: &str = "RUSTFS_SCANNER_ENABLED";
|
||||
pub(crate) const ENV_SCANNER_ENABLED_DEPRECATED: &str = "RUSTFS_ENABLE_SCANNER";
|
||||
pub(crate) const ENV_HEAL_ENABLED: &str = "RUSTFS_HEAL_ENABLED";
|
||||
pub(crate) const ENV_HEAL_ENABLED_DEPRECATED: &str = "RUSTFS_ENABLE_HEAL";
|
||||
const LOG_COMPONENT_MAIN: &str = "main";
|
||||
const LOG_SUBSYSTEM_STARTUP: &str = "startup";
|
||||
const EVENT_BACKGROUND_SERVICES_CONFIGURED: &str = "background_services_configured";
|
||||
|
||||
pub(crate) fn scanner_enabled_from_env() -> bool {
|
||||
get_env_bool_with_aliases(ENV_SCANNER_ENABLED, &[ENV_SCANNER_ENABLED_DEPRECATED], true)
|
||||
}
|
||||
|
||||
pub(crate) fn heal_enabled_from_env() -> bool {
|
||||
get_env_bool_with_aliases(ENV_HEAL_ENABLED, &[ENV_HEAL_ENABLED_DEPRECATED], true)
|
||||
}
|
||||
|
||||
pub(crate) async fn init_background_service_runtime(store: Arc<ECStore>) -> Result<bool> {
|
||||
let _ = create_ahm_services_cancel_token();
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::server::{is_audit_module_enabled, is_notify_module_enabled};
|
||||
use crate::module_switches::{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;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::startup_background::{heal_enabled_from_env, scanner_enabled_from_env};
|
||||
use crate::module_switches::{heal_enabled_from_env, scanner_enabled_from_env};
|
||||
use crate::storage::storage_api::runtime_sources_consumer::EndpointServerPools;
|
||||
use jiff::Timestamp;
|
||||
use rmp_serde::Deserializer;
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
# cycle|left_layer<->right_layer
|
||||
cycle|app<->infra
|
||||
cycle|app<->interface
|
||||
cycle|composition<->infra
|
||||
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::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
|
||||
@@ -29,8 +25,6 @@ dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::snapshot_depe
|
||||
dep|rustfs/src/runtime_sources.rs|infra->app|crate::app::context
|
||||
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::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
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::refresh_notify_module_enabled
|
||||
dep|rustfs/src/storage/rpc/http_service.rs|infra->interface|crate::server::RPC_PREFIX
|
||||
@@ -40,5 +34,3 @@ dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::servic
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::server::MODULE_SWITCHES_SIGNAL_SUBSYSTEM
|
||||
dep|rustfs/src/storage/rpc/node_service/heal.rs|infra->composition|crate::startup_background::heal_enabled_from_env
|
||||
dep|rustfs/src/storage/rpc/node_service/heal.rs|infra->composition|crate::startup_background::scanner_enabled_from_env
|
||||
|
||||
Reference in New Issue
Block a user