use std::sync::{Arc, LazyLock, Mutex}; use crate::cache::{CacheConfig, CachePools}; use crate::error::BabyError; pub static GITBABY_CACHE: LazyLock>>> = LazyLock::new(|| Mutex::new(None)); pub fn try_global_cache() -> Option> { let guard = GITBABY_CACHE.lock().ok()?; guard.clone() } pub fn init_global_cache(cfg: CacheConfig) -> Result, BabyError> { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() .map_err(|source| { BabyError::Custom(format!( "build one-shot tokio runtime for init_global_cache: {}", source )) })?; let pools = rt.block_on(CachePools::open(cfg))?; install(pools) } pub async fn init_global_cache_async(cfg: CacheConfig) -> Result, BabyError> { let pools = CachePools::open(cfg).await?; install(pools) } fn install(pools: Arc) -> Result, BabyError> { let mut guard = GITBABY_CACHE .lock() .map_err(|source| BabyError::Custom(format!("global cache mutex poisoned: {}", source)))?; *guard = Some(pools.clone()); Ok(pools) } pub async fn shutdown_global_cache() -> Result<(), BabyError> { let pools = { let mut guard = GITBABY_CACHE.lock().map_err(|source| { BabyError::Custom(format!("global cache mutex poisoned: {}", source)) })?; guard.take() }; if let Some(pools) = pools && Arc::strong_count(&pools) == 1 { pools.close().await?; } Ok(()) }