1use std::collections::HashMap;
16use std::sync::LazyLock;
17use std::sync::atomic::{AtomicU64, Ordering};
18use tokio::sync::RwLock;
19use tonic::transport::Channel;
20
21pub static GLOBAL_LOCAL_NODE_NAME: LazyLock<RwLock<String>> = LazyLock::new(|| RwLock::new("".to_string()));
22pub static GLOBAL_RUSTFS_HOST: LazyLock<RwLock<String>> = LazyLock::new(|| RwLock::new("".to_string()));
23pub static GLOBAL_RUSTFS_PORT: LazyLock<RwLock<String>> = LazyLock::new(|| RwLock::new("9000".to_string()));
24pub static GLOBAL_RUSTFS_ADDR: LazyLock<RwLock<String>> = LazyLock::new(|| RwLock::new("".to_string()));
25pub static GLOBAL_CONN_MAP: LazyLock<RwLock<HashMap<String, Channel>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
26pub static GLOBAL_ROOT_CERT: LazyLock<RwLock<Option<Vec<u8>>>> = LazyLock::new(|| RwLock::new(None));
27pub static GLOBAL_MTLS_IDENTITY: LazyLock<RwLock<Option<MtlsIdentityPem>>> = LazyLock::new(|| RwLock::new(None));
28pub static GLOBAL_OUTBOUND_TLS_GENERATION: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
29
30#[derive(Clone, Copy, Debug, Eq, PartialEq)]
32pub enum ConnectionEvictionLogLevel {
33 Warn,
34 Info,
35 Debug,
36}
37
38pub async fn set_global_local_node_name(name: &str) {
43 *GLOBAL_LOCAL_NODE_NAME.write().await = name.to_string();
44}
45
46pub async fn get_global_local_node_name() -> String {
51 GLOBAL_LOCAL_NODE_NAME.read().await.clone()
52}
53
54pub fn try_get_global_local_node_name() -> Option<String> {
56 GLOBAL_LOCAL_NODE_NAME
57 .try_read()
58 .ok()
59 .map(|name| name.clone())
60 .filter(|name| !name.is_empty())
61}
62
63pub async fn set_global_addr(addr: &str) {
68 *GLOBAL_RUSTFS_ADDR.write().await = addr.to_string();
69}
70
71pub async fn get_global_rustfs_host() -> String {
73 GLOBAL_RUSTFS_HOST.read().await.clone()
74}
75
76pub async fn get_global_addr() -> String {
78 GLOBAL_RUSTFS_ADDR.read().await.clone()
79}
80
81pub async fn set_global_root_cert(cert: Vec<u8>) {
88 *GLOBAL_ROOT_CERT.write().await = Some(cert);
89}
90
91pub async fn clear_global_root_cert() {
93 *GLOBAL_ROOT_CERT.write().await = None;
94}
95
96pub async fn get_global_root_cert() -> Option<Vec<u8>> {
98 GLOBAL_ROOT_CERT.read().await.clone()
99}
100
101pub async fn set_global_mtls_identity(identity: Option<MtlsIdentityPem>) {
108 *GLOBAL_MTLS_IDENTITY.write().await = identity;
109}
110
111pub async fn get_global_mtls_identity() -> Option<MtlsIdentityPem> {
113 GLOBAL_MTLS_IDENTITY.read().await.clone()
114}
115
116pub fn set_global_outbound_tls_generation(generation: u64) {
118 GLOBAL_OUTBOUND_TLS_GENERATION.store(generation, Ordering::Relaxed);
119}
120
121pub fn get_global_outbound_tls_generation() -> u64 {
123 GLOBAL_OUTBOUND_TLS_GENERATION.load(Ordering::Relaxed)
124}
125
126pub async fn evict_connection(addr: &str) {
133 evict_connection_with_log_level(addr, ConnectionEvictionLogLevel::Info).await;
134}
135
136pub async fn evict_connection_with_log_level(addr: &str, log_level: ConnectionEvictionLogLevel) {
138 let removed = GLOBAL_CONN_MAP.write().await.remove(addr);
139 if removed.is_some() {
140 match log_level {
141 ConnectionEvictionLogLevel::Warn => {
142 tracing::warn!(
143 addr = %addr,
144 "Removed cached gRPC connection so future RPCs will attempt to establish a fresh channel"
145 );
146 }
147 ConnectionEvictionLogLevel::Info => {
148 tracing::info!(
149 addr = %addr,
150 "Removed cached gRPC connection so future RPCs will attempt to establish a fresh channel"
151 );
152 }
153 ConnectionEvictionLogLevel::Debug => {
154 tracing::debug!(
155 addr = %addr,
156 "Removed cached gRPC connection so future RPCs will attempt to establish a fresh channel"
157 );
158 }
159 }
160 }
161}
162
163pub async fn cached_connection(addr: &str) -> Option<Channel> {
165 GLOBAL_CONN_MAP.read().await.get(addr).cloned()
166}
167
168pub async fn cache_connection(addr: String, channel: Channel) {
170 GLOBAL_CONN_MAP.write().await.insert(addr, channel);
171}
172
173pub async fn has_cached_connection(addr: &str) -> bool {
181 GLOBAL_CONN_MAP.read().await.contains_key(addr)
182}
183
184pub async fn clear_all_connections() {
186 let mut map = GLOBAL_CONN_MAP.write().await;
187 let count = map.len();
188 map.clear();
189 if count > 0 {
190 tracing::warn!("Cleared {} cached connections from global map", count);
191 }
192}
193#[derive(Clone, Debug)]
198pub struct MtlsIdentityPem {
199 pub cert_pem: Vec<u8>,
200 pub key_pem: Vec<u8>,
201}