mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-06 05:17:42 +00:00
refactor(ecstore): move the bucket metadata system into InstanceContext (#4622)
backlog#1052 S3, third slice — the hard blocker for a second embedded server's service stage. GLOBAL_BUCKET_METADATA_SYS was a process-global OnceLock whose init ran .set().unwrap(): a second instance's service startup panicked the whole process. The system it guards is inherently per-store (it holds the store handle and that store's bucket→metadata cache), so it now lives on the store's own InstanceContext: - init_bucket_metadata_sys writes the cell of the store it was handed (api.ctx) — no signature change — and keeps the double-init fail-fast, now scoped to the instance (assert on the per-context set). The dist-erasure check for the refresh loop reads the same context. - get_global_bucket_metadata_sys / the crate-private getter behind the ~20 get_*_config helpers resolve through the current_ctx() facade — the published store's context, or bootstrap before that — so every existing reader keeps its exact single-instance behavior. - New acceptance test: two real stores in one process each initialize their own metadata system (the old global cell panicked right there), plus a shared builder extracted from the store-graph test. 201 bucket/metadata regression tests green.
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
use super::global::TypeLocalDiskSetDrives;
|
||||
use crate::bucket::bandwidth::monitor::Monitor;
|
||||
use crate::bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, TransitionState};
|
||||
use crate::bucket::metadata_sys::BucketMetadataSys;
|
||||
use crate::bucket::replication::{DynReplicationPool, ReplicationStats};
|
||||
use crate::disk::DiskStore;
|
||||
use crate::layout::endpoints::{EndpointServerPools, SetupType};
|
||||
@@ -139,6 +140,13 @@ pub struct InstanceContext {
|
||||
local_disk_map: Arc<RwLock<HashMap<String, Option<DiskStore>>>>,
|
||||
local_disk_id_map: Arc<RwLock<HashMap<Uuid, String>>>,
|
||||
local_disk_set_drives: Arc<RwLock<TypeLocalDiskSetDrives>>,
|
||||
/// This instance's bucket metadata system (backlog#1052 S3).
|
||||
///
|
||||
/// Set once when storage startup initializes bucket metadata for this
|
||||
/// instance's store; holds the store handle plus the bucket→metadata
|
||||
/// cache, so it is inherently per-store. Replaces the process-global
|
||||
/// bucket-metadata static (whose double-init panicked process-wide).
|
||||
bucket_metadata_sys: OnceLock<Arc<RwLock<BucketMetadataSys>>>,
|
||||
/// This instance's background-services cancellation token (Phase 5 Slice 13,
|
||||
/// backlog#939).
|
||||
///
|
||||
@@ -178,6 +186,7 @@ impl InstanceContext {
|
||||
local_disk_map: Arc::new(RwLock::new(HashMap::new())),
|
||||
local_disk_id_map: Arc::new(RwLock::new(HashMap::new())),
|
||||
local_disk_set_drives: Arc::new(RwLock::new(Vec::new())),
|
||||
bucket_metadata_sys: OnceLock::new(),
|
||||
background_cancel_token: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
@@ -310,6 +319,18 @@ impl InstanceContext {
|
||||
self.local_disk_set_drives.clone()
|
||||
}
|
||||
|
||||
/// Set this instance's bucket metadata system (once). Returns `false` if
|
||||
/// it was already initialized — the caller preserves the old fail-fast
|
||||
/// contract, now scoped to the instance instead of the process.
|
||||
pub fn init_bucket_metadata_sys(&self, sys: Arc<RwLock<BucketMetadataSys>>) -> bool {
|
||||
self.bucket_metadata_sys.set(sys).is_ok()
|
||||
}
|
||||
|
||||
/// This instance's bucket metadata system, if initialized.
|
||||
pub fn bucket_metadata_sys(&self) -> Option<Arc<RwLock<BucketMetadataSys>>> {
|
||||
self.bucket_metadata_sys.get().cloned()
|
||||
}
|
||||
|
||||
/// Set this instance's background-services cancellation token (once).
|
||||
pub fn init_background_cancel_token(&self, token: CancellationToken) -> Result<(), CancellationToken> {
|
||||
self.background_cancel_token.set(token)
|
||||
@@ -366,6 +387,7 @@ impl std::fmt::Debug for InstanceContext {
|
||||
.field("expiry_state_set", &self.expiry_state.get().is_some())
|
||||
.field("transition_state_set", &self.transition_state.get().is_some())
|
||||
.field("bucket_monitor_set", &self.bucket_monitor.get().is_some())
|
||||
.field("bucket_metadata_sys_set", &self.bucket_metadata_sys.get().is_some())
|
||||
.field("replication_stats_set", &self.replication_stats.get().is_some())
|
||||
.field("replication_pool_set", &self.replication_pool.get().is_some())
|
||||
.field("background_cancel_token_set", &self.background_cancel_token.get().is_some())
|
||||
|
||||
Reference in New Issue
Block a user