From 809e77d5db7050125de4aaac15b8de994bb9748a Mon Sep 17 00:00:00 2001 From: Henry Guo Date: Mon, 29 Jun 2026 14:14:26 +0800 Subject: [PATCH] fix(runtime): keep lock clients available during startup (#4042) --- rustfs/src/app/context.rs | 46 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/rustfs/src/app/context.rs b/rustfs/src/app/context.rs index 4da3ebada..031527f0f 100644 --- a/rustfs/src/app/context.rs +++ b/rustfs/src/app/context.rs @@ -193,12 +193,12 @@ pub fn resolve_runtime_port() -> Option { /// Resolve lock client using AppContext-first precedence. pub fn resolve_lock_client() -> Option> { - resolve_lock_client_with(get_global_app_context()) + resolve_lock_client_with_startup_fallback(get_global_app_context(), runtime_sources::lock_client) } /// Resolve lock clients using AppContext-first precedence. pub fn resolve_lock_clients_handle() -> Option>> { - resolve_lock_clients_handle_with(get_global_app_context()) + resolve_lock_clients_handle_with_startup_fallback(get_global_app_context(), runtime_sources::lock_clients) } /// Resolve performance metrics using AppContext-first precedence. @@ -383,10 +383,27 @@ fn resolve_lock_client_with(context: Option>) -> Option(context: Option>, fallback: F) -> Option> +where + F: FnOnce() -> Option>, +{ + resolve_lock_client_with(context).or_else(fallback) +} + fn resolve_lock_clients_handle_with(context: Option>) -> Option>> { context.and_then(|context| context.lock_clients().handle()) } +fn resolve_lock_clients_handle_with_startup_fallback( + context: Option>, + fallback: F, +) -> Option>> +where + F: FnOnce() -> Option>>, +{ + resolve_lock_clients_handle_with(context).or_else(fallback) +} + fn resolve_performance_metrics_with(context: Option>) -> Option> { context.map(|context| context.performance_metrics().handle()) } @@ -880,6 +897,31 @@ mod tests { } } + #[test] + fn lock_client_resolver_uses_startup_fallback_before_app_context() { + let fallback_lock_client: Arc = Arc::new(LocalClient::new()); + + let resolved = resolve_lock_client_with_startup_fallback(None, || Some(fallback_lock_client.clone())) + .expect("startup fallback lock client"); + + assert!(Arc::ptr_eq(&resolved, &fallback_lock_client)); + } + + #[test] + fn lock_clients_resolver_uses_startup_fallback_before_app_context() { + let fallback_lock_client: Arc = Arc::new(LocalClient::new()); + let mut fallback_lock_clients = HashMap::new(); + fallback_lock_clients.insert("startup-node:9000".to_string(), fallback_lock_client.clone()); + + let resolved = resolve_lock_clients_handle_with_startup_fallback(None, || Some(fallback_lock_clients.clone())) + .expect("startup fallback lock clients"); + + assert!(Arc::ptr_eq( + resolved.get("startup-node:9000").expect("startup fallback lock client entry"), + &fallback_lock_client + )); + } + #[tokio::test] async fn resolver_helpers_are_context_first_and_empty_when_context_is_absent() { let (_temp_dir, object_store, endpoints) = test_store().await;