use crate::cache::{CacheManager, CacheStats};
use crate::error::{QuickDbError, QuickDbResult};
use crate::id_generator::{IdGenerator, MongoAutoIncrementGenerator};
use crate::model::ModelMeta;
use crate::pool::{ConnectionPool, ExtendedPoolConfig, PooledConnection};
use crate::types::{DatabaseConfig, DatabaseType, IdType};
use dashmap::DashMap;
use rat_logger::{debug, error, info, warn};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use tokio::time::{Duration, interval};
use super::PoolManager;
impl PoolManager {
pub fn get_cache_manager(&self, alias: &str) -> QuickDbResult<Arc<CacheManager>> {
if let Some(cache_manager) = self.cache_managers.get(alias) {
Ok(cache_manager.clone())
} else {
Err(crate::quick_error!(
config,
format!("数据库 {} 没有配置缓存管理器", alias)
))
}
}
pub async fn get_cache_stats(&self, alias: &str) -> QuickDbResult<CacheStats> {
let cache_manager = self.get_cache_manager(alias)?;
Ok(cache_manager.get_stats().await?)
}
pub async fn clear_cache(&self, alias: &str) -> QuickDbResult<()> {
let cache_manager = self.get_cache_manager(alias)?;
cache_manager.clear_all().await;
info!("已清理数据库 {} 的缓存", alias);
Ok(())
}
pub async fn clear_all_caches(&self) -> QuickDbResult<()> {
for entry in self.cache_managers.iter() {
let alias = entry.key();
let cache_manager = entry.value();
cache_manager.clear_all().await;
info!("已清理数据库 {} 的缓存", alias);
}
Ok(())
}
pub(crate) async fn start_cleanup_task(&self) {
let mut cleanup_handle = self.cleanup_handle.write().await;
if cleanup_handle.is_some() {
return;
}
let pools = self.pools.clone();
let handle = tokio::spawn(async move {
let mut interval = interval(Duration::from_secs(300));
debug!("启动连接池清理任务");
loop {
interval.tick().await;
debug!("执行连接池清理任务");
for entry in pools.iter() {
let alias = entry.key();
let pool = entry.value();
debug!("清理连接池过期连接: 别名={}", alias);
pool.cleanup_expired_connections().await;
}
debug!("连接池清理任务完成");
}
});
*cleanup_handle = Some(handle);
}
pub async fn stop_cleanup_task(&self) {
let mut cleanup_handle = self.cleanup_handle.write().await;
if let Some(handle) = cleanup_handle.take() {
handle.abort();
debug!("连接池清理任务已停止");
}
}
}