refactor: expose runtime fallback boundaries (#3954)

This commit is contained in:
Zhengchao An
2026-06-27 18:57:51 +08:00
committed by GitHub
parent cdebdeca61
commit 4732f4ee2d
2 changed files with 162 additions and 244 deletions
+33 -11
View File
@@ -5,7 +5,7 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context ## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-runtime-context-fallback-signature-cleanup` - Branch: `overtrue/arch-runtime-fallback-boundary-cleanup`
- 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/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205/API-206/API-207/API-208/API-209/API-210/API-211/API-212/API-213/API-214/API-215/API-216/API-217/API-218/API-219/API-220/API-221/API-222/API-223/API-224/API-225/API-226/API-227/API-228/API-229/API-230/API-231/API-232/API-233/API-234/API-235/API-236/API-237/API-238/API-239/API-240/API-241/API-242/API-243/API-244/API-245/API-246/API-247/API-248/API-249/API-250/API-251/API-252/API-253/API-254/CTX-002`. - 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/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205/API-206/API-207/API-208/API-209/API-210/API-211/API-212/API-213/API-214/API-215/API-216/API-217/API-218/API-219/API-220/API-221/API-222/API-223/API-224/API-225/API-226/API-227/API-228/API-229/API-230/API-231/API-232/API-233/API-234/API-235/API-236/API-237/API-238/API-239/API-240/API-241/API-242/API-243/API-244/API-245/API-246/API-247/API-248/API-249/API-250/API-251/API-252/API-253/API-254/CTX-002`.
- Current baseline also includes API-255 from PR #3923, API-256 from PR - Current baseline also includes API-255 from PR #3923, API-256 from PR
#3925, CFG-009 from PR #3927, C-007/C-009 from PR #3935, C-008/C-010 #3925, CFG-009 from PR #3927, C-007/C-009 from PR #3935, C-008/C-010
@@ -20,18 +20,19 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
runtime facade consumer batch from PR #3948, the GLOB-007 runtime facade runtime facade consumer batch from PR #3948, the GLOB-007 runtime facade
alias sweep from PR #3949, the GLOB-007 object-store fallback removal from alias sweep from PR #3949, the GLOB-007 object-store fallback removal from
PR #3950, the GLOB-007 notification-system/server-config fallback removal PR #3950, the GLOB-007 notification-system/server-config fallback removal
from PR #3951, and the GLOB-007 optional runtime handle fallback removal from PR #3951, the GLOB-007 optional runtime handle fallback removal from
from PR #3952. PR #3952, and the GLOB-007 AppContext-only fallback signature cleanup from
- Current phase PR: GLOB-007 AppContext-only fallback signature cleanup. PR #3953.
- Based on: `origin/main` after PR #3952 merged. - Current phase PR: GLOB-007 runtime resolver fallback boundary cleanup.
- Based on: `origin/main` after PR #3953 merged.
- PR type for this branch: `ci-gate`. - PR type for this branch: `ci-gate`.
- Runtime behavior changes: none intended beyond the PR #3952 optional - Runtime behavior changes: none intended; public runtime facades keep their
no-context behavior. existing no-AppContext fallback behavior.
- Rust code changes: remove stale fallback closure parameters from - Rust code changes: move remaining resolver helper fallback parameters to the
AppContext-only resolver helpers for object-store, notification-system, public facade boundary for KMS, IAM, TLS, metrics, S3 Select, node identity,
server-config, and optional runtime handles. tier/expiry, credentials, runtime port, and buffer config reads.
- CI/script changes: none intended. - CI/script changes: none intended.
- Docs changes: update this progress ledger for the fallback signature cleanup. - Docs changes: update this progress ledger for the fallback boundary cleanup.
## Phase 0 Tasks ## Phase 0 Tasks
@@ -2822,6 +2823,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
- Current slice: remove stale fallback closure parameters from - Current slice: remove stale fallback closure parameters from
AppContext-only resolver helpers after their no-context behavior no longer AppContext-only resolver helpers after their no-context behavior no longer
consults legacy globals. consults legacy globals.
- Current slice: move the remaining resolver helper fallback parameters to
public runtime facade boundaries, preserving no-AppContext fallback behavior
while making private helpers context-only.
- Remaining work: remove the next fallback family per PR only after scans - Remaining work: remove the next fallback family per PR only after scans
prove no production caller depends on it. prove no production caller depends on it.
- Verification: focused RustFS compile and admin test-target compile, - Verification: focused RustFS compile and admin test-target compile,
@@ -6090,6 +6094,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
| Expert | Status | Notes | | Expert | Status | Notes |
|---|---|---| |---|---|---|
| Quality/architecture | pass | GLOB-007 moves the remaining resolver helper fallback parameters out to public facade boundaries, making private helper paths context-only without hiding fallback closures. |
| Migration preservation | pass | Public runtime facade names, return types, and no-AppContext fallback behavior are preserved; only helper signatures and focused resolver tests change. |
| Testing/verification | pass | Focused resolver test, compile, formatting, architecture guard, fallback-boundary residual scan, diff hygiene, diff-added Rust risk scan, Rust quality scan, and full `make pre-pr` passed before PR. |
| Quality/architecture | pass | GLOB-007 removes stale fallback closure parameters from resolver helpers whose no-context behavior is already AppContext-only, making hidden fallback reintroduction harder. | | Quality/architecture | pass | GLOB-007 removes stale fallback closure parameters from resolver helpers whose no-context behavior is already AppContext-only, making hidden fallback reintroduction harder. |
| Migration preservation | pass | Public runtime facade names and return types stay unchanged; this is a signature cleanup for private helper paths and test coverage after PR #3952. | | Migration preservation | pass | Public runtime facade names and return types stay unchanged; this is a signature cleanup for private helper paths and test coverage after PR #3952. |
| Testing/verification | pass | Focused resolver test passed; compile, formatting, architecture guard, fallback-parameter residual scan, diff hygiene, diff-added Rust risk scan, and full `make pre-pr` are required before PR. | | Testing/verification | pass | Focused resolver test passed; compile, formatting, architecture guard, fallback-parameter residual scan, diff hygiene, diff-added Rust risk scan, and full `make pre-pr` are required before PR. |
@@ -6480,6 +6487,21 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
Passed before push: Passed before push:
- Issue #660 GLOB-007 runtime resolver fallback boundary cleanup:
- Branch freshness check: moved onto `origin/main` after PR #3953 merged.
- `cargo test -p rustfs --lib app::context::tests::resolver_helpers_are_context_first_and_empty_when_context_is_absent`:
passed.
- `cargo check -p rustfs --lib`: passed.
- `cargo fmt --all`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- Resolver fallback-boundary residual scan: passed.
- Diff-added Rust risk scan: passed.
- Rust code quality scan: passed.
- Three-expert review: passed.
- `make pre-pr`: passed (`nextest`: 6917 passed, 112 skipped; doctests passed).
- Issue #660 GLOB-007 AppContext-only fallback signature cleanup: - Issue #660 GLOB-007 AppContext-only fallback signature cleanup:
- Branch freshness check: rebased onto `origin/main` after PR #3952 merged. - Branch freshness check: rebased onto `origin/main` after PR #3952 merged.
- `cargo test -p rustfs --lib app::context::tests::resolver_helpers_are_context_first_and_fallback_when_context_is_absent`: - `cargo test -p rustfs --lib app::context::tests::resolver_helpers_are_context_first_and_fallback_when_context_is_absent`:
+129 -233
View File
@@ -42,27 +42,34 @@ use rustfs_lock::LockClient;
use rustfs_s3select_api::{QueryResult, server::dbms::DatabaseManagerSystem}; use rustfs_s3select_api::{QueryResult, server::dbms::DatabaseManagerSystem};
use rustfs_tls_runtime::{GlobalPublishedOutboundTlsState, TlsGeneration}; use rustfs_tls_runtime::{GlobalPublishedOutboundTlsState, TlsGeneration};
use s3s::dto::SelectObjectContentInput; use s3s::dto::SelectObjectContentInput;
use std::{collections::HashMap, future::Future, sync::Arc, time::SystemTime}; use std::{collections::HashMap, sync::Arc, time::SystemTime};
use tokio::sync::RwLock; use tokio::sync::RwLock;
/// Resolve KMS runtime service manager using AppContext-first precedence. /// Resolve KMS runtime service manager using AppContext-first precedence.
pub fn resolve_kms_runtime_service_manager() -> Option<Arc<KmsServiceManager>> { pub fn resolve_kms_runtime_service_manager() -> Option<Arc<KmsServiceManager>> {
resolve_kms_runtime_service_manager_with(get_global_app_context(), || default_kms_runtime_interface().service_manager()) resolve_kms_runtime_service_manager_with(get_global_app_context())
.or_else(|| default_kms_runtime_interface().service_manager())
} }
/// Resolve or initialize the KMS runtime service manager using AppContext-first precedence. /// Resolve or initialize the KMS runtime service manager using AppContext-first precedence.
pub fn resolve_or_init_kms_runtime_service_manager() -> Arc<KmsServiceManager> { pub fn resolve_or_init_kms_runtime_service_manager() -> Arc<KmsServiceManager> {
resolve_or_init_kms_runtime_service_manager_with(get_global_app_context(), runtime_sources::init_kms_service_manager) resolve_or_init_kms_runtime_service_manager_with(get_global_app_context())
.unwrap_or_else(runtime_sources::init_kms_service_manager)
} }
/// Resolve KMS encryption service using AppContext-first precedence. /// Resolve KMS encryption service using AppContext-first precedence.
pub async fn resolve_encryption_service() -> Option<Arc<ObjectEncryptionService>> { pub async fn resolve_encryption_service() -> Option<Arc<ObjectEncryptionService>> {
resolve_encryption_service_with(get_global_app_context(), runtime_sources::encryption_service).await if let Some(service) = resolve_encryption_service_with(get_global_app_context()).await {
return Some(service);
}
runtime_sources::encryption_service().await
} }
/// Resolve outbound TLS generation using AppContext-first precedence. /// Resolve outbound TLS generation using AppContext-first precedence.
pub fn resolve_outbound_tls_generation() -> TlsGeneration { pub fn resolve_outbound_tls_generation() -> TlsGeneration {
resolve_outbound_tls_generation_with(get_global_app_context(), || default_outbound_tls_runtime_interface().generation()) resolve_outbound_tls_generation_with(get_global_app_context())
.unwrap_or_else(|| default_outbound_tls_runtime_interface().generation())
} }
#[cfg(test)] #[cfg(test)]
@@ -77,12 +84,12 @@ pub async fn resolve_outbound_tls_state() -> GlobalPublishedOutboundTlsState {
/// Resolve IAM readiness using AppContext-first precedence. /// Resolve IAM readiness using AppContext-first precedence.
pub fn resolve_iam_ready() -> bool { pub fn resolve_iam_ready() -> bool {
resolve_iam_ready_with(get_global_app_context(), runtime_sources::iam_is_ready) resolve_iam_ready_with(get_global_app_context()).unwrap_or_else(runtime_sources::iam_is_ready)
} }
/// Resolve IAM system handle using AppContext-first precedence. /// Resolve IAM system handle using AppContext-first precedence.
pub fn resolve_iam_handle() -> Option<Arc<IamSys<ObjectStore>>> { pub fn resolve_iam_handle() -> Option<Arc<IamSys<ObjectStore>>> {
resolve_iam_handle_with(get_global_app_context(), runtime_sources::iam_handle) resolve_iam_handle_with(get_global_app_context()).or_else(runtime_sources::iam_handle)
} }
/// Resolve OIDC system handle using AppContext-first precedence. /// Resolve OIDC system handle using AppContext-first precedence.
@@ -97,7 +104,11 @@ pub fn publish_oidc_handle(oidc: Arc<OidcSys>) -> bool {
/// Resolve a ready IAM system handle using AppContext-first precedence. /// Resolve a ready IAM system handle using AppContext-first precedence.
pub fn resolve_ready_iam_handle() -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> { pub fn resolve_ready_iam_handle() -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> {
resolve_ready_iam_handle_with(get_global_app_context(), runtime_sources::ready_iam_handle) if let Some(context) = get_global_app_context() {
return resolve_ready_iam_handle_with(context);
}
runtime_sources::ready_iam_handle()
} }
/// Resolve token signing key using AppContext-first precedence. /// Resolve token signing key using AppContext-first precedence.
@@ -171,13 +182,16 @@ pub fn resolve_boot_time() -> Option<SystemTime> {
/// Resolve daily tier transition statistics using AppContext-first precedence. /// Resolve daily tier transition statistics using AppContext-first precedence.
pub fn resolve_daily_tier_stats() -> DailyAllTierStats { pub fn resolve_daily_tier_stats() -> DailyAllTierStats {
resolve_daily_tier_stats_with(get_global_app_context(), || default_tier_stats_interface().daily_all()) resolve_daily_tier_stats_with(get_global_app_context()).unwrap_or_else(|| default_tier_stats_interface().daily_all())
} }
/// Resolve scanner metrics report using AppContext-first precedence. /// Resolve scanner metrics report using AppContext-first precedence.
pub async fn resolve_scanner_metrics_report() -> ScannerMetricsReport { pub async fn resolve_scanner_metrics_report() -> ScannerMetricsReport {
resolve_scanner_metrics_report_with(get_global_app_context(), || async { default_scanner_metrics_interface().report().await }) if let Some(report) = resolve_scanner_metrics_report_with(get_global_app_context()).await {
.await return report;
}
default_scanner_metrics_interface().report().await
} }
/// Resolve deployment identity using AppContext-first precedence. /// Resolve deployment identity using AppContext-first precedence.
@@ -187,7 +201,7 @@ pub fn resolve_deployment_id() -> Option<String> {
/// Resolve runtime port using AppContext-first precedence. /// Resolve runtime port using AppContext-first precedence.
pub fn resolve_runtime_port() -> u16 { pub fn resolve_runtime_port() -> u16 {
resolve_runtime_port_with(get_global_app_context(), || default_runtime_port_interface().get()) resolve_runtime_port_with(get_global_app_context()).unwrap_or_else(|| default_runtime_port_interface().get())
} }
/// Resolve lock client using AppContext-first precedence. /// Resolve lock client using AppContext-first precedence.
@@ -202,12 +216,12 @@ pub fn resolve_lock_clients_handle() -> Option<HashMap<String, Arc<dyn LockClien
/// Resolve performance metrics using AppContext-first precedence. /// Resolve performance metrics using AppContext-first precedence.
pub fn resolve_performance_metrics() -> Arc<PerformanceMetrics> { pub fn resolve_performance_metrics() -> Arc<PerformanceMetrics> {
resolve_performance_metrics_with(get_global_app_context(), || default_performance_metrics_interface().handle()) resolve_performance_metrics_with(get_global_app_context()).unwrap_or_else(|| default_performance_metrics_interface().handle())
} }
/// Resolve internode metrics using AppContext-first precedence. /// Resolve internode metrics using AppContext-first precedence.
pub fn resolve_internode_metrics() -> Arc<InternodeMetrics> { pub fn resolve_internode_metrics() -> Arc<InternodeMetrics> {
resolve_internode_metrics_with(get_global_app_context(), || default_internode_metrics_interface().handle()) resolve_internode_metrics_with(get_global_app_context()).unwrap_or_else(|| default_internode_metrics_interface().handle())
} }
/// Resolve S3 Select database using AppContext-first precedence. /// Resolve S3 Select database using AppContext-first precedence.
@@ -215,20 +229,29 @@ pub async fn resolve_s3select_db(
input: SelectObjectContentInput, input: SelectObjectContentInput,
enable_debug: bool, enable_debug: bool,
) -> QueryResult<Arc<dyn DatabaseManagerSystem + Send + Sync>> { ) -> QueryResult<Arc<dyn DatabaseManagerSystem + Send + Sync>> {
resolve_s3select_db_with(get_global_app_context(), input, enable_debug, |input, enable_debug| async move { if let Some(context) = get_global_app_context() {
default_s3select_db_interface().get(input, enable_debug).await return resolve_s3select_db_with(context, input, enable_debug).await;
}) }
.await
default_s3select_db_interface().get(input, enable_debug).await
} }
/// Resolve local node name using AppContext-first precedence. /// Resolve local node name using AppContext-first precedence.
pub async fn resolve_local_node_name() -> String { pub async fn resolve_local_node_name() -> String {
resolve_local_node_name_with(get_global_app_context(), runtime_sources::local_node_name).await if let Some(node_name) = resolve_local_node_name_with(get_global_app_context()).await {
return node_name;
}
runtime_sources::local_node_name().await
} }
/// Resolve action credentials using AppContext-first precedence. /// Resolve action credentials using AppContext-first precedence.
pub fn resolve_action_credentials() -> Option<Credentials> { pub fn resolve_action_credentials() -> Option<Credentials> {
resolve_action_credentials_with(get_global_app_context(), || default_action_credential_interface().get()) if let Some(context) = get_global_app_context() {
return resolve_action_credentials_with(context);
}
default_action_credential_interface().get()
} }
/// Resolve region using AppContext-first precedence. /// Resolve region using AppContext-first precedence.
@@ -238,12 +261,12 @@ pub fn resolve_region() -> Option<s3s::region::Region> {
/// Resolve tier config handle using AppContext-first precedence. /// Resolve tier config handle using AppContext-first precedence.
pub fn resolve_tier_config_handle() -> Arc<RwLock<TierConfigMgr>> { pub fn resolve_tier_config_handle() -> Arc<RwLock<TierConfigMgr>> {
resolve_tier_config_handle_with(get_global_app_context(), || default_tier_config_interface().handle()) resolve_tier_config_handle_with(get_global_app_context()).unwrap_or_else(|| default_tier_config_interface().handle())
} }
/// Resolve lifecycle expiry state using AppContext-first precedence. /// Resolve lifecycle expiry state using AppContext-first precedence.
pub fn resolve_expiry_state_handle() -> Arc<RwLock<ExpiryState>> { pub fn resolve_expiry_state_handle() -> Arc<RwLock<ExpiryState>> {
resolve_expiry_state_handle_with(get_global_app_context(), || default_expiry_state_interface().handle()) resolve_expiry_state_handle_with(get_global_app_context()).unwrap_or_else(|| default_expiry_state_interface().handle())
} }
/// Resolve server config using AppContext-first precedence. /// Resolve server config using AppContext-first precedence.
@@ -270,47 +293,24 @@ pub fn publish_storage_class_config(config: StorageClassConfig) {
/// Resolve buffer profile config using AppContext-first precedence. /// Resolve buffer profile config using AppContext-first precedence.
pub fn resolve_buffer_config() -> RustFSBufferConfig { pub fn resolve_buffer_config() -> RustFSBufferConfig {
resolve_buffer_config_with(get_global_app_context(), || default_buffer_config_interface().get()) resolve_buffer_config_with(get_global_app_context()).unwrap_or_else(|| default_buffer_config_interface().get())
} }
fn resolve_kms_runtime_service_manager_with( fn resolve_kms_runtime_service_manager_with(context: Option<Arc<AppContext>>) -> Option<Arc<KmsServiceManager>> {
context: Option<Arc<AppContext>>, context.and_then(|context| context.kms_runtime().service_manager())
fallback: impl FnOnce() -> Option<Arc<KmsServiceManager>>,
) -> Option<Arc<KmsServiceManager>> {
context
.and_then(|context| context.kms_runtime().service_manager())
.or_else(fallback)
} }
fn resolve_or_init_kms_runtime_service_manager_with( fn resolve_or_init_kms_runtime_service_manager_with(context: Option<Arc<AppContext>>) -> Option<Arc<KmsServiceManager>> {
context: Option<Arc<AppContext>>, context.and_then(|context| context.kms_runtime().service_manager())
fallback: impl FnOnce() -> Arc<KmsServiceManager>,
) -> Arc<KmsServiceManager> {
context
.and_then(|context| context.kms_runtime().service_manager())
.unwrap_or_else(fallback)
} }
async fn resolve_encryption_service_with<F, Fut>( async fn resolve_encryption_service_with(context: Option<Arc<AppContext>>) -> Option<Arc<ObjectEncryptionService>> {
context: Option<Arc<AppContext>>, let manager = context.and_then(|context| context.kms_runtime().service_manager())?;
fallback: F, manager.get_encryption_service().await
) -> Option<Arc<ObjectEncryptionService>>
where
F: FnOnce() -> Fut,
Fut: Future<Output = Option<Arc<ObjectEncryptionService>>>,
{
if let Some(manager) = context.and_then(|context| context.kms_runtime().service_manager()) {
return manager.get_encryption_service().await;
}
fallback().await
} }
fn resolve_outbound_tls_generation_with( fn resolve_outbound_tls_generation_with(context: Option<Arc<AppContext>>) -> Option<TlsGeneration> {
context: Option<Arc<AppContext>>, context.map(|context| context.outbound_tls_runtime().generation())
fallback: impl FnOnce() -> TlsGeneration,
) -> TlsGeneration {
context.map_or_else(fallback, |context| context.outbound_tls_runtime().generation())
} }
async fn resolve_outbound_tls_state_with(context: Option<Arc<AppContext>>) -> GlobalPublishedOutboundTlsState { async fn resolve_outbound_tls_state_with(context: Option<Arc<AppContext>>) -> GlobalPublishedOutboundTlsState {
@@ -321,15 +321,12 @@ async fn resolve_outbound_tls_state_with(context: Option<Arc<AppContext>>) -> Gl
default_outbound_tls_runtime_interface().state().await default_outbound_tls_runtime_interface().state().await
} }
fn resolve_iam_ready_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> bool) -> bool { fn resolve_iam_ready_with(context: Option<Arc<AppContext>>) -> Option<bool> {
context.map_or_else(fallback, |context| context.iam().is_ready()) context.map(|context| context.iam().is_ready())
} }
fn resolve_iam_handle_with( fn resolve_iam_handle_with(context: Option<Arc<AppContext>>) -> Option<Arc<IamSys<ObjectStore>>> {
context: Option<Arc<AppContext>>, context.map(|context| context.iam().handle())
fallback: impl FnOnce() -> Option<Arc<IamSys<ObjectStore>>>,
) -> Option<Arc<IamSys<ObjectStore>>> {
context.map(|context| context.iam().handle()).or_else(fallback)
} }
fn resolve_oidc_handle_with(context: Option<Arc<AppContext>>) -> Option<Arc<OidcSys>> { fn resolve_oidc_handle_with(context: Option<Arc<AppContext>>) -> Option<Arc<OidcSys>> {
@@ -340,19 +337,12 @@ fn publish_oidc_handle_with(context: Option<Arc<AppContext>>, oidc: Arc<OidcSys>
context.is_some_and(|context| context.publish_oidc_handle(oidc)) context.is_some_and(|context| context.publish_oidc_handle(oidc))
} }
fn resolve_ready_iam_handle_with( fn resolve_ready_iam_handle_with(context: Arc<AppContext>) -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> {
context: Option<Arc<AppContext>>, if context.iam().is_ready() {
fallback: impl FnOnce() -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>>, return Ok(context.iam().handle());
) -> rustfs_iam::error::Result<Arc<IamSys<ObjectStore>>> {
if let Some(context) = context {
if context.iam().is_ready() {
return Ok(context.iam().handle());
}
return Err(IamError::IamSysNotInitialized);
} }
fallback() Err(IamError::IamSysNotInitialized)
} }
fn resolve_token_signing_key_with(context: Option<Arc<AppContext>>) -> Option<String> { fn resolve_token_signing_key_with(context: Option<Arc<AppContext>>) -> Option<String> {
@@ -383,23 +373,16 @@ fn resolve_boot_time_with(context: Option<Arc<AppContext>>) -> Option<SystemTime
context.and_then(|context| context.boot_time().get()) context.and_then(|context| context.boot_time().get())
} }
fn resolve_daily_tier_stats_with( fn resolve_daily_tier_stats_with(context: Option<Arc<AppContext>>) -> Option<DailyAllTierStats> {
context: Option<Arc<AppContext>>, context.map(|context| context.tier_stats().daily_all())
fallback: impl FnOnce() -> DailyAllTierStats,
) -> DailyAllTierStats {
context.map_or_else(fallback, |context| context.tier_stats().daily_all())
} }
async fn resolve_scanner_metrics_report_with<F, Fut>(context: Option<Arc<AppContext>>, fallback: F) -> ScannerMetricsReport async fn resolve_scanner_metrics_report_with(context: Option<Arc<AppContext>>) -> Option<ScannerMetricsReport> {
where
F: FnOnce() -> Fut,
Fut: Future<Output = ScannerMetricsReport>,
{
if let Some(context) = context { if let Some(context) = context {
return context.scanner_metrics().report().await; return Some(context.scanner_metrics().report().await);
} }
fallback().await None
} }
#[cfg(test)] #[cfg(test)]
@@ -415,8 +398,8 @@ fn resolve_deployment_id_with(context: Option<Arc<AppContext>>) -> Option<String
context.and_then(|context| context.deployment_id().get()) context.and_then(|context| context.deployment_id().get())
} }
fn resolve_runtime_port_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> u16) -> u16 { fn resolve_runtime_port_with(context: Option<Arc<AppContext>>) -> Option<u16> {
context.map_or_else(fallback, |context| context.runtime_port().get()) context.map(|context| context.runtime_port().get())
} }
fn resolve_lock_client_with(context: Option<Arc<AppContext>>) -> Option<Arc<dyn LockClient>> { fn resolve_lock_client_with(context: Option<Arc<AppContext>>) -> Option<Arc<dyn LockClient>> {
@@ -427,76 +410,44 @@ fn resolve_lock_clients_handle_with(context: Option<Arc<AppContext>>) -> Option<
context.and_then(|context| context.lock_clients().handle()) context.and_then(|context| context.lock_clients().handle())
} }
fn resolve_performance_metrics_with( fn resolve_performance_metrics_with(context: Option<Arc<AppContext>>) -> Option<Arc<PerformanceMetrics>> {
context: Option<Arc<AppContext>>, context.map(|context| context.performance_metrics().handle())
fallback: impl FnOnce() -> Arc<PerformanceMetrics>,
) -> Arc<PerformanceMetrics> {
context.map_or_else(fallback, |context| context.performance_metrics().handle())
} }
fn resolve_internode_metrics_with( fn resolve_internode_metrics_with(context: Option<Arc<AppContext>>) -> Option<Arc<InternodeMetrics>> {
context: Option<Arc<AppContext>>, context.map(|context| context.internode_metrics().handle())
fallback: impl FnOnce() -> Arc<InternodeMetrics>,
) -> Arc<InternodeMetrics> {
context.map_or_else(fallback, |context| context.internode_metrics().handle())
} }
async fn resolve_s3select_db_with<F, Fut>( async fn resolve_s3select_db_with(
context: Option<Arc<AppContext>>, context: Arc<AppContext>,
input: SelectObjectContentInput, input: SelectObjectContentInput,
enable_debug: bool, enable_debug: bool,
fallback: F, ) -> QueryResult<Arc<dyn DatabaseManagerSystem + Send + Sync>> {
) -> QueryResult<Arc<dyn DatabaseManagerSystem + Send + Sync>> context.s3select_db().get(input, enable_debug).await
where
F: FnOnce(SelectObjectContentInput, bool) -> Fut,
Fut: Future<Output = QueryResult<Arc<dyn DatabaseManagerSystem + Send + Sync>>>,
{
if let Some(context) = context {
return context.s3select_db().get(input, enable_debug).await;
}
fallback(input, enable_debug).await
} }
async fn resolve_local_node_name_with<F, Fut>(context: Option<Arc<AppContext>>, fallback: F) -> String async fn resolve_local_node_name_with(context: Option<Arc<AppContext>>) -> Option<String> {
where
F: FnOnce() -> Fut,
Fut: Future<Output = String>,
{
if let Some(context) = context { if let Some(context) = context {
return context.local_node_name().get().await; return Some(context.local_node_name().get().await);
} }
fallback().await None
} }
fn resolve_action_credentials_with( fn resolve_action_credentials_with(context: Arc<AppContext>) -> Option<Credentials> {
context: Option<Arc<AppContext>>, context.action_credentials().get()
fallback: impl FnOnce() -> Option<Credentials>,
) -> Option<Credentials> {
context
.map(|context| context.action_credentials().get())
.unwrap_or_else(fallback)
} }
fn resolve_region_with(context: Option<Arc<AppContext>>) -> Option<s3s::region::Region> { fn resolve_region_with(context: Option<Arc<AppContext>>) -> Option<s3s::region::Region> {
context.and_then(|context| context.region().get()) context.and_then(|context| context.region().get())
} }
fn resolve_tier_config_handle_with( fn resolve_tier_config_handle_with(context: Option<Arc<AppContext>>) -> Option<Arc<RwLock<TierConfigMgr>>> {
context: Option<Arc<AppContext>>, context.map(|context| context.tier_config().handle())
fallback: impl FnOnce() -> Arc<RwLock<TierConfigMgr>>,
) -> Arc<RwLock<TierConfigMgr>> {
context.map(|context| context.tier_config().handle()).unwrap_or_else(fallback)
} }
fn resolve_expiry_state_handle_with( fn resolve_expiry_state_handle_with(context: Option<Arc<AppContext>>) -> Option<Arc<RwLock<ExpiryState>>> {
context: Option<Arc<AppContext>>, context.map(|context| context.expiry_state().handle())
fallback: impl FnOnce() -> Arc<RwLock<ExpiryState>>,
) -> Arc<RwLock<ExpiryState>> {
context
.map(|context| context.expiry_state().handle())
.unwrap_or_else(fallback)
} }
fn resolve_server_config_with(context: Option<Arc<AppContext>>) -> Option<Config> { fn resolve_server_config_with(context: Option<Arc<AppContext>>) -> Option<Config> {
@@ -523,11 +474,8 @@ fn publish_storage_class_config_with(
} }
} }
fn resolve_buffer_config_with( fn resolve_buffer_config_with(context: Option<Arc<AppContext>>) -> Option<RustFSBufferConfig> {
context: Option<Arc<AppContext>>, context.map(|context| context.buffer_config().get())
fallback: impl FnOnce() -> RustFSBufferConfig,
) -> RustFSBufferConfig {
context.map_or_else(fallback, |context| context.buffer_config().get())
} }
#[cfg(test)] #[cfg(test)]
@@ -954,28 +902,20 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
async fn resolver_helpers_are_context_first_and_fallback_when_context_is_absent() { async fn resolver_helpers_are_context_first_and_empty_when_context_is_absent() {
let (_temp_dir, object_store, endpoints) = test_store().await; let (_temp_dir, object_store, endpoints) = test_store().await;
let context_kms = Arc::new(KmsServiceManager::new()); 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 bucket_metadata = Arc::new(RwLock::new(BucketMetadataSys::new(object_store.clone())));
let context_replication_stats = Arc::new(ReplicationStats::new()); let context_replication_stats = Arc::new(ReplicationStats::new());
let context_boot_time = SystemTime::UNIX_EPOCH + Duration::from_secs(10); let context_boot_time = SystemTime::UNIX_EPOCH + Duration::from_secs(10);
let mut context_daily_tier_stats = DailyAllTierStats::new(); let mut context_daily_tier_stats = DailyAllTierStats::new();
context_daily_tier_stats.insert("CONTEXT".to_string(), Default::default()); context_daily_tier_stats.insert("CONTEXT".to_string(), Default::default());
let mut fallback_daily_tier_stats = DailyAllTierStats::new();
fallback_daily_tier_stats.insert("FALLBACK".to_string(), Default::default());
let context_scanner_metrics = ScannerMetricsReport { let context_scanner_metrics = ScannerMetricsReport {
current_cycle: 7, current_cycle: 7,
..Default::default() ..Default::default()
}; };
let fallback_scanner_metrics = ScannerMetricsReport {
current_cycle: 13,
..Default::default()
};
let tier_config = TierConfigMgr::new(); let tier_config = TierConfigMgr::new();
let context_expiry_state = ExpiryState::new(); let context_expiry_state = ExpiryState::new();
let fallback_expiry_state = ExpiryState::new();
let server_config = Config::new(); let server_config = Config::new();
let context_server_config_published = Arc::new(AtomicUsize::new(0)); let context_server_config_published = Arc::new(AtomicUsize::new(0));
let fallback_server_config_published = Arc::new(AtomicUsize::new(0)); let fallback_server_config_published = Arc::new(AtomicUsize::new(0));
@@ -984,18 +924,13 @@ mod tests {
let buffer_config = RustFSBufferConfig::new(WorkloadProfile::AiTraining); let buffer_config = RustFSBufferConfig::new(WorkloadProfile::AiTraining);
let context_lock_client: Arc<dyn LockClient> = Arc::new(LocalClient::new()); let context_lock_client: Arc<dyn LockClient> = Arc::new(LocalClient::new());
let context_node_name = "context-node".to_string(); let context_node_name = "context-node".to_string();
let fallback_node_name = "fallback-node".to_string();
let context_deployment_id = "context-deployment".to_string(); let context_deployment_id = "context-deployment".to_string();
let context_runtime_port = 19000; let context_runtime_port = 19000;
let fallback_runtime_port = 29000;
let mut context_lock_clients = HashMap::new(); let mut context_lock_clients = HashMap::new();
context_lock_clients.insert("context-node:9000".to_string(), context_lock_client.clone()); context_lock_clients.insert("context-node:9000".to_string(), context_lock_client.clone());
let context_performance_metrics = Arc::new(PerformanceMetrics::new()); let context_performance_metrics = Arc::new(PerformanceMetrics::new());
let fallback_performance_metrics = Arc::new(PerformanceMetrics::new());
let context_internode_metrics = Arc::new(InternodeMetrics::default()); let context_internode_metrics = Arc::new(InternodeMetrics::default());
let fallback_internode_metrics = Arc::new(InternodeMetrics::default());
let context_s3select_db: Arc<dyn DatabaseManagerSystem + Send + Sync> = Arc::new(TestS3SelectDb); let context_s3select_db: Arc<dyn DatabaseManagerSystem + Send + Sync> = Arc::new(TestS3SelectDb);
let fallback_s3select_db: Arc<dyn DatabaseManagerSystem + Send + Sync> = Arc::new(TestS3SelectDb);
let context_outbound_tls_state = GlobalPublishedOutboundTlsState { let context_outbound_tls_state = GlobalPublishedOutboundTlsState {
generation: TlsGeneration(41), generation: TlsGeneration(41),
root_ca_pem: Some(b"context-root-ca".to_vec()), root_ca_pem: Some(b"context-root-ca".to_vec()),
@@ -1005,10 +940,6 @@ mod tests {
access_key: "context-access-key".to_string(), access_key: "context-access-key".to_string(),
..Default::default() ..Default::default()
}; };
let fallback_credentials = Credentials {
access_key: "fallback-access-key".to_string(),
..Default::default()
};
let context_region: s3s::region::Region = "context-region".parse().expect("test region"); let context_region: s3s::region::Region = "context-region".parse().expect("test region");
let context_oidc_sys = match OidcSys::empty() { let context_oidc_sys = match OidcSys::empty() {
Ok(sys) => sys, Ok(sys) => sys,
@@ -1109,23 +1040,22 @@ mod tests {
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_kms_runtime_service_manager_with(Some(context.clone()), || Some(fallback_kms.clone())) &resolve_kms_runtime_service_manager_with(Some(context.clone())).expect("context KMS runtime"),
.expect("context KMS runtime"),
&context_kms &context_kms
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_or_init_kms_runtime_service_manager_with(Some(context.clone()), || fallback_kms.clone()), &resolve_or_init_kms_runtime_service_manager_with(Some(context.clone())).expect("context KMS runtime"),
&context_kms &context_kms
)); ));
assert_eq!( assert_eq!(
resolve_outbound_tls_generation_with(Some(context.clone()), || TlsGeneration(99)), resolve_outbound_tls_generation_with(Some(context.clone())).expect("context outbound TLS generation"),
context_outbound_tls_state.generation context_outbound_tls_state.generation
); );
assert_eq!( assert_eq!(
resolve_outbound_tls_state_with(Some(context.clone())).await.generation, resolve_outbound_tls_state_with(Some(context.clone())).await.generation,
context_outbound_tls_state.generation context_outbound_tls_state.generation
); );
assert!(resolve_iam_ready_with(Some(context.clone()), || false)); assert!(resolve_iam_ready_with(Some(context.clone())).expect("context IAM ready"));
let resolved_oidc = resolve_oidc_handle_with(Some(context.clone())); let resolved_oidc = resolve_oidc_handle_with(Some(context.clone()));
assert!(resolved_oidc.as_ref().is_some_and(|oidc| Arc::ptr_eq(oidc, &context_oidc))); assert!(resolved_oidc.as_ref().is_some_and(|oidc| Arc::ptr_eq(oidc, &context_oidc)));
assert!(publish_oidc_handle_with(Some(context.clone()), fallback_oidc.clone())); assert!(publish_oidc_handle_with(Some(context.clone()), fallback_oidc.clone()));
@@ -1152,11 +1082,14 @@ mod tests {
context_boot_time context_boot_time
); );
assert!( assert!(
resolve_daily_tier_stats_with(Some(context.clone()), || fallback_daily_tier_stats.clone()).contains_key("CONTEXT") resolve_daily_tier_stats_with(Some(context.clone()))
.expect("context daily tier stats")
.contains_key("CONTEXT")
); );
assert_eq!( assert_eq!(
resolve_scanner_metrics_report_with(Some(context.clone()), || async { fallback_scanner_metrics.clone() }) resolve_scanner_metrics_report_with(Some(context.clone()))
.await .await
.expect("context scanner metrics")
.current_cycle, .current_cycle,
context_scanner_metrics.current_cycle context_scanner_metrics.current_cycle
); );
@@ -1172,7 +1105,7 @@ mod tests {
context_deployment_id context_deployment_id
); );
assert_eq!( assert_eq!(
resolve_runtime_port_with(Some(context.clone()), || fallback_runtime_port), resolve_runtime_port_with(Some(context.clone())).expect("context runtime port"),
context_runtime_port context_runtime_port
); );
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
@@ -1187,38 +1120,38 @@ mod tests {
&context_lock_client &context_lock_client
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_performance_metrics_with(Some(context.clone()), || fallback_performance_metrics.clone()), &resolve_performance_metrics_with(Some(context.clone())).expect("context performance metrics"),
&context_performance_metrics &context_performance_metrics
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_internode_metrics_with(Some(context.clone()), || fallback_internode_metrics.clone()), &resolve_internode_metrics_with(Some(context.clone())).expect("context internode metrics"),
&context_internode_metrics &context_internode_metrics
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_s3select_db_with(Some(context.clone()), test_select_input(), false, |_input, _enable_debug| async { &resolve_s3select_db_with(context.clone(), test_select_input(), false)
Ok(fallback_s3select_db.clone()) .await
}) .expect("context S3 Select DB"),
.await
.expect("context S3 Select DB"),
&context_s3select_db &context_s3select_db
)); ));
assert_eq!( assert_eq!(
resolve_local_node_name_with(Some(context.clone()), || async { fallback_node_name.clone() }).await, resolve_local_node_name_with(Some(context.clone()))
.await
.expect("context local node name"),
context_node_name context_node_name
); );
assert_eq!( assert_eq!(
resolve_action_credentials_with(Some(context.clone()), || Some(fallback_credentials.clone())) resolve_action_credentials_with(context.clone())
.expect("context action credentials") .expect("context action credentials")
.access_key, .access_key,
context_credentials.access_key context_credentials.access_key
); );
assert_eq!(resolve_region_with(Some(context.clone())).expect("context region"), context_region); assert_eq!(resolve_region_with(Some(context.clone())).expect("context region"), context_region);
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_tier_config_handle_with(Some(context.clone()), TierConfigMgr::new), &resolve_tier_config_handle_with(Some(context.clone())).expect("context tier config"),
&tier_config &tier_config
)); ));
assert!(Arc::ptr_eq( assert!(Arc::ptr_eq(
&resolve_expiry_state_handle_with(Some(context.clone()), || fallback_expiry_state.clone()), &resolve_expiry_state_handle_with(Some(context.clone())).expect("context expiry state"),
&context_expiry_state &context_expiry_state
)); ));
assert_eq!( assert_eq!(
@@ -1238,21 +1171,17 @@ mod tests {
assert_eq!(context_storage_class_published.load(Ordering::SeqCst), 1); assert_eq!(context_storage_class_published.load(Ordering::SeqCst), 1);
assert_eq!(fallback_storage_class_published.load(Ordering::SeqCst), 0); assert_eq!(fallback_storage_class_published.load(Ordering::SeqCst), 0);
assert_eq!( assert_eq!(
resolve_buffer_config_with(Some(context), || RustFSBufferConfig::new(WorkloadProfile::GeneralPurpose)).workload, resolve_buffer_config_with(Some(context))
.expect("context buffer config")
.workload,
WorkloadProfile::AiTraining WorkloadProfile::AiTraining
); );
assert!(Arc::ptr_eq( assert!(resolve_kms_runtime_service_manager_with(None).is_none());
&resolve_kms_runtime_service_manager_with(None, || Some(fallback_kms.clone())).expect("fallback KMS runtime"), assert!(resolve_or_init_kms_runtime_service_manager_with(None).is_none());
&fallback_kms assert!(resolve_outbound_tls_generation_with(None).is_none());
)); assert!(resolve_iam_ready_with(None).is_none());
assert!(Arc::ptr_eq( assert!(resolve_iam_handle_with(None).is_none());
&resolve_or_init_kms_runtime_service_manager_with(None, || fallback_kms.clone()),
&fallback_kms
));
assert_eq!(resolve_outbound_tls_generation_with(None, || TlsGeneration(99)), TlsGeneration(99));
assert!(!resolve_iam_ready_with(None, || false));
assert!(resolve_iam_handle_with(None, || None).is_none());
assert!(resolve_oidc_handle_with(None).is_none()); assert!(resolve_oidc_handle_with(None).is_none());
assert!(resolve_token_signing_key_with(None).is_none()); assert!(resolve_token_signing_key_with(None).is_none());
assert!(!publish_oidc_handle_with(None, context_oidc)); assert!(!publish_oidc_handle_with(None, context_oidc));
@@ -1262,50 +1191,20 @@ mod tests {
assert!(resolve_object_store_handle_with(None).is_none()); assert!(resolve_object_store_handle_with(None).is_none());
assert!(resolve_replication_stats_handle_with(None).is_none()); assert!(resolve_replication_stats_handle_with(None).is_none());
assert!(resolve_boot_time_with(None).is_none()); assert!(resolve_boot_time_with(None).is_none());
assert!(resolve_daily_tier_stats_with(None, || fallback_daily_tier_stats.clone()).contains_key("FALLBACK")); assert!(resolve_daily_tier_stats_with(None).is_none());
assert_eq!( assert!(resolve_scanner_metrics_report_with(None).await.is_none());
resolve_scanner_metrics_report_with(None, || async { fallback_scanner_metrics.clone() })
.await
.current_cycle,
fallback_scanner_metrics.current_cycle
);
assert!(resolve_endpoints_handle_with(None).is_none()); assert!(resolve_endpoints_handle_with(None).is_none());
assert!(resolve_deployment_id_with(None).is_none()); assert!(resolve_deployment_id_with(None).is_none());
assert_eq!(resolve_runtime_port_with(None, || fallback_runtime_port), fallback_runtime_port); assert!(resolve_runtime_port_with(None).is_none());
assert!(resolve_lock_client_with(None).is_none()); assert!(resolve_lock_client_with(None).is_none());
assert!(resolve_lock_clients_handle_with(None).is_none()); assert!(resolve_lock_clients_handle_with(None).is_none());
assert!(Arc::ptr_eq( assert!(resolve_performance_metrics_with(None).is_none());
&resolve_performance_metrics_with(None, || fallback_performance_metrics.clone()), assert!(resolve_internode_metrics_with(None).is_none());
&fallback_performance_metrics assert!(resolve_local_node_name_with(None).await.is_none());
)); assert!(resolve_action_credentials().is_none());
assert!(Arc::ptr_eq(
&resolve_internode_metrics_with(None, || fallback_internode_metrics.clone()),
&fallback_internode_metrics
));
assert!(Arc::ptr_eq(
&resolve_s3select_db_with(None, test_select_input(), false, |_input, _enable_debug| async {
Ok(fallback_s3select_db.clone())
})
.await
.expect("fallback S3 Select DB"),
&fallback_s3select_db
));
assert_eq!(
resolve_local_node_name_with(None, || async { fallback_node_name.clone() }).await,
fallback_node_name
);
assert_eq!(
resolve_action_credentials_with(None, || Some(fallback_credentials.clone()))
.expect("fallback action credentials")
.access_key,
fallback_credentials.access_key
);
assert!(resolve_region_with(None).is_none()); assert!(resolve_region_with(None).is_none());
assert!(Arc::ptr_eq(&resolve_tier_config_handle_with(None, || tier_config.clone()), &tier_config)); assert!(resolve_tier_config_handle_with(None).is_none());
assert!(Arc::ptr_eq( assert!(resolve_expiry_state_handle_with(None).is_none());
&resolve_expiry_state_handle_with(None, || fallback_expiry_state.clone()),
&fallback_expiry_state
));
assert!(resolve_server_config_with(None).is_none()); assert!(resolve_server_config_with(None).is_none());
publish_server_config_with(None, Config::new(), |config| { publish_server_config_with(None, Config::new(), |config| {
drop(config); drop(config);
@@ -1317,9 +1216,6 @@ mod tests {
fallback_storage_class_published.fetch_add(1, Ordering::SeqCst); fallback_storage_class_published.fetch_add(1, Ordering::SeqCst);
}); });
assert_eq!(fallback_storage_class_published.load(Ordering::SeqCst), 1); assert_eq!(fallback_storage_class_published.load(Ordering::SeqCst), 1);
assert_eq!( assert!(resolve_buffer_config_with(None).is_none());
resolve_buffer_config_with(None, || RustFSBufferConfig::new(WorkloadProfile::DataAnalytics)).workload,
WorkloadProfile::DataAnalytics
);
} }
} }