mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
refactor(ecstore): move lifecycle expiry and transition state into InstanceContext (#4488)
This commit is contained in:
@@ -51,7 +51,6 @@ use crate::store::ECStore;
|
||||
use async_channel::{Receiver as A_Receiver, Sender as A_Sender, bounded};
|
||||
use futures::Future;
|
||||
use http::HeaderMap;
|
||||
use lazy_static::lazy_static;
|
||||
use rustfs_common::metrics::{
|
||||
IlmAction, Metrics, ScannerLifecycleExpiryStateUpdate, ScannerLifecycleTransitionStateUpdate, global_metrics,
|
||||
};
|
||||
@@ -119,17 +118,15 @@ const DEFAULT_STALE_UPLOADS_CLEANUP_INTERVAL: StdDuration = StdDuration::from_se
|
||||
const DATE_EXPIRY_EXISTING_OBJECTS_GRACE_SECS: i64 = 5;
|
||||
const EXPIRY_WORKER_QUEUE_CAPACITY: usize = 1000;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_EXPIRY_STATE: Arc<RwLock<ExpiryState>> = ExpiryState::new();
|
||||
pub static ref GLOBAL_TRANSITION_STATE: Arc<TransitionState> = TransitionState::new();
|
||||
}
|
||||
|
||||
// Phase 5 (backlog#939): lifecycle expiry/transition state moved into the
|
||||
// per-instance `InstanceContext`; these owner helpers forward to the current
|
||||
// instance's context (lazily materialized, shared for single-instance).
|
||||
pub fn get_global_expiry_state() -> Arc<RwLock<ExpiryState>> {
|
||||
GLOBAL_EXPIRY_STATE.clone()
|
||||
crate::runtime::global::current_ctx().expiry_state()
|
||||
}
|
||||
|
||||
pub fn get_global_transition_state() -> Arc<TransitionState> {
|
||||
GLOBAL_TRANSITION_STATE.clone()
|
||||
crate::runtime::global::current_ctx().transition_state()
|
||||
}
|
||||
|
||||
fn resolve_transition_worker_count() -> (i64, i64, i64) {
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
//! startup writes and post-construction reads hit the same cell and
|
||||
//! single-instance behavior is byte-for-byte unchanged.
|
||||
|
||||
use crate::bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, TransitionState};
|
||||
use crate::layout::endpoints::{EndpointServerPools, SetupType};
|
||||
use crate::services::event_notification::EventNotifier;
|
||||
use crate::services::tier::tier::TierConfigMgr;
|
||||
@@ -96,6 +97,16 @@ pub struct InstanceContext {
|
||||
/// Lazily materialized like the tier config manager; holds the instance's
|
||||
/// notification target list. Replaces the eager process static.
|
||||
event_notifier: OnceLock<Arc<RwLock<EventNotifier>>>,
|
||||
/// This instance's lifecycle expiry state (Phase 5 Slice 9, backlog#939).
|
||||
///
|
||||
/// Lazily materialized; holds the instance's expiry worker channels/stats.
|
||||
/// Replaces the eager process static.
|
||||
expiry_state: OnceLock<Arc<RwLock<ExpiryState>>>,
|
||||
/// This instance's lifecycle transition state (Phase 5 Slice 9, backlog#939).
|
||||
///
|
||||
/// Lazily materialized; holds the instance's transition workers/stats.
|
||||
/// Replaces the eager process static.
|
||||
transition_state: OnceLock<Arc<TransitionState>>,
|
||||
}
|
||||
|
||||
impl InstanceContext {
|
||||
@@ -120,6 +131,8 @@ impl InstanceContext {
|
||||
endpoints: OnceLock::new(),
|
||||
tier_config_mgr: OnceLock::new(),
|
||||
event_notifier: OnceLock::new(),
|
||||
expiry_state: OnceLock::new(),
|
||||
transition_state: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +198,18 @@ impl InstanceContext {
|
||||
self.event_notifier.get_or_init(EventNotifier::new).clone()
|
||||
}
|
||||
|
||||
/// This instance's lifecycle expiry state, materializing it on first
|
||||
/// access. Shared for the lifetime of the instance.
|
||||
pub fn expiry_state(&self) -> Arc<RwLock<ExpiryState>> {
|
||||
self.expiry_state.get_or_init(ExpiryState::new).clone()
|
||||
}
|
||||
|
||||
/// This instance's lifecycle transition state, materializing it on first
|
||||
/// access. Shared for the lifetime of the instance.
|
||||
pub fn transition_state(&self) -> Arc<TransitionState> {
|
||||
self.transition_state.get_or_init(TransitionState::new).clone()
|
||||
}
|
||||
|
||||
/// Update this instance's erasure setup type.
|
||||
pub async fn update_erasure_type(&self, setup_type: SetupType) {
|
||||
*self.erasure_kind.write().await = setup_type;
|
||||
@@ -228,6 +253,8 @@ impl std::fmt::Debug for InstanceContext {
|
||||
.field("endpoints", &self.endpoints)
|
||||
.field("tier_config_mgr_set", &self.tier_config_mgr.get().is_some())
|
||||
.field("event_notifier_set", &self.event_notifier.get().is_some())
|
||||
.field("expiry_state_set", &self.expiry_state.get().is_some())
|
||||
.field("transition_state_set", &self.transition_state.get().is_some())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
@@ -489,4 +516,18 @@ mod tests {
|
||||
"fresh contexts must not share an event notifier"
|
||||
);
|
||||
}
|
||||
|
||||
// Lifecycle expiry/transition state are each stable within an instance and
|
||||
// distinct across instances.
|
||||
#[tokio::test]
|
||||
async fn lifecycle_state_is_stable_within_and_distinct_across_instances() {
|
||||
let ctx_a = InstanceContext::new();
|
||||
let ctx_b = InstanceContext::new();
|
||||
|
||||
assert!(Arc::ptr_eq(&ctx_a.expiry_state(), &ctx_a.expiry_state()));
|
||||
assert!(Arc::ptr_eq(&ctx_a.transition_state(), &ctx_a.transition_state()));
|
||||
|
||||
assert!(!Arc::ptr_eq(&ctx_a.expiry_state(), &ctx_b.expiry_state()));
|
||||
assert!(!Arc::ptr_eq(&ctx_a.transition_state(), &ctx_b.transition_state()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::{
|
||||
use crate::bucket::bandwidth::monitor::Monitor;
|
||||
use crate::disk::endpoint::Endpoint;
|
||||
use crate::{
|
||||
bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, GLOBAL_EXPIRY_STATE, GLOBAL_TRANSITION_STATE, TransitionState},
|
||||
bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, TransitionState},
|
||||
bucket::metadata_sys::{BucketMetadataSys, get_global_bucket_metadata_sys},
|
||||
bucket::replication::{
|
||||
DynReplicationPool, ReplicationStats,
|
||||
@@ -391,11 +391,11 @@ pub(crate) fn tier_config_mgr_handle() -> Arc<RwLock<TierConfigMgr>> {
|
||||
}
|
||||
|
||||
pub fn expiry_state_handle() -> Arc<RwLock<ExpiryState>> {
|
||||
GLOBAL_EXPIRY_STATE.clone()
|
||||
crate::runtime::global::current_ctx().expiry_state()
|
||||
}
|
||||
|
||||
pub fn transition_state_handle() -> Arc<TransitionState> {
|
||||
GLOBAL_TRANSITION_STATE.clone()
|
||||
crate::runtime::global::current_ctx().transition_state()
|
||||
}
|
||||
|
||||
pub(crate) fn event_notifier_handle() -> Arc<RwLock<EventNotifier>> {
|
||||
|
||||
Reference in New Issue
Block a user