1use crate::{
4 cache::{
5 AuthSnapshotCache, EpisodeTasksCache, MemberAllCache, MemberTaskCountsCache,
6 MangaTranNameCache, RssFileLock,
7 },
8 config::AppConfig,
9 dev::error_log,
10 dev::paths::resolve_error_log_path,
11 runner,
12 service::rss_service,
13 utils::error_log as file_error_log,
14};
15use sqlx::MySqlPool;
16use std::sync::Arc;
17use std::time::Instant;
18
19#[derive(Clone)]
21pub struct AppState {
22 pub db: MySqlPool,
24 pub config: Arc<AppConfig>,
26 pub http_client: reqwest::Client,
28 pub manga_tran_name_cache: MangaTranNameCache,
30 pub manga_ori_name_cache: MangaTranNameCache,
32 pub member_all_cache: MemberAllCache,
34 pub auth_snapshot_cache: AuthSnapshotCache,
36 pub episode_tasks_cache: EpisodeTasksCache,
38 pub member_task_counts_cache: MemberTaskCountsCache,
40 pub rss_file_lock: Arc<RssFileLock>,
42 pub started_at: Instant,
44}
45
46impl AppState {
47 pub async fn new(config: AppConfig) -> anyhow::Result<Self> {
49 let db = sqlx::mysql::MySqlPoolOptions::new()
50 .max_connections(config.database.max_connections)
51 .connect(&config.database.url)
52 .await?;
53 runner::run_all(&db).await?;
54 rss_service::ensure_rss_dir(&config).await?;
55 let http_client = reqwest::Client::builder()
56 .pool_max_idle_per_host(8)
57 .build()
58 .map_err(|e| anyhow::anyhow!("构建 HTTP 客户端失败: {e}"))?;
59
60 if matches!(config.profile.as_str(), "dev" | "dev-h2") {
61 error_log::init_pool(db.clone());
62 }
63
64 file_error_log::init(resolve_error_log_path(&config.dev_console));
65
66 Ok(Self {
67 db,
68 config: Arc::new(config),
69 http_client,
70 manga_tran_name_cache: crate::cache::new_manga_tran_name_cache(),
71 manga_ori_name_cache: crate::cache::new_manga_tran_name_cache(),
72 member_all_cache: crate::cache::new_member_all_cache(),
73 auth_snapshot_cache: crate::cache::new_auth_snapshot_cache(),
74 episode_tasks_cache: crate::cache::new_episode_tasks_cache(),
75 member_task_counts_cache: crate::cache::new_member_task_counts_cache(),
76 rss_file_lock: Arc::new(RssFileLock::new()),
77 started_at: Instant::now(),
78 })
79 }
80}