//! 共享应用状态。 //! //! 采样任务(写)与 HTTP handler(读)通过一个被 `RwLock` 保护的 //! `Stats` 快照通信。`AppState` 可廉价 `clone`(内部是 `Arc`)。 use std::sync::Arc; use tokio::sync::RwLock; use crate::auth::{self, DevGate, UserStore, WallUserStore}; use crate::folders::{FolderRegistry, FolderStore}; use crate::monitor::Stats; use crate::photos::PhotoStore; use crate::weather::WeatherService; #[derive(Clone)] pub struct AppState { /// 最新一次采样快照。 pub snapshot: Arc>, /// 用户校验后端(MySQL 或内置兜底):内部已是连接池/只读 map,`Arc` 共享即可。 pub users: Arc, /// 开发者入口门:合法入口 hash 集合,只读共享。 pub gate: Arc, /// 天气/定位服务(自带每日限流 + 缓存)。 pub weather: Arc, /// 照片墙用户校验后端(wall_users 表)。 pub wall_users: Arc, /// 照片墙图片仓库(按用户隔离的磁盘目录)。 pub photos: PhotoStore, /// 特殊文件夹注册表(白名单)。 pub folders: FolderRegistry, /// 特殊文件夹图片仓库(按文件夹隔离的磁盘目录)。 pub folder_photos: FolderStore, } impl AppState { pub fn new() -> Self { // 一个连接池给登录校验与入口门共用(克隆是廉价的、共享底层连接)。 let pool = auth::db_pool_from_env(); Self { snapshot: Arc::new(RwLock::new(Stats::default())), users: Arc::new(UserStore::new(pool.clone())), gate: Arc::new(DevGate::new(pool.clone())), weather: Arc::new(WeatherService::from_env()), wall_users: Arc::new(WallUserStore::new(pool.clone())), photos: PhotoStore::from_env(), folders: FolderRegistry::from_env(), folder_photos: FolderStore::from_env(), } } }