2024-11-26 12:19:57 +08:00
|
|
|
mod security;
|
|
|
|
mod common;
|
|
|
|
mod storage;
|
|
|
|
mod api;
|
2024-11-25 22:43:24 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
use crate::common::config;
|
2024-11-26 12:19:57 +08:00
|
|
|
use common::error::{CustomErrorInto, CustomResult};
|
2024-11-25 03:36:24 +08:00
|
|
|
use rocket::Shutdown;
|
2024-11-19 00:20:31 +08:00
|
|
|
use std::sync::Arc;
|
2024-11-28 23:10:00 +08:00
|
|
|
use storage::sql;
|
2024-11-19 00:20:31 +08:00
|
|
|
use tokio::sync::Mutex;
|
2024-11-25 03:36:24 +08:00
|
|
|
pub struct AppState {
|
2024-11-26 12:19:57 +08:00
|
|
|
db: Arc<Mutex<Option<sql::Database>>>,
|
2024-11-25 03:36:24 +08:00
|
|
|
shutdown: Arc<Mutex<Option<Shutdown>>>,
|
|
|
|
restart_progress: Arc<Mutex<bool>>,
|
2024-11-09 00:05:18 +08:00
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
2024-11-20 19:53:18 +08:00
|
|
|
impl AppState {
|
2024-11-25 17:59:18 +08:00
|
|
|
pub fn new() -> Self {
|
2024-11-25 03:36:24 +08:00
|
|
|
Self {
|
|
|
|
db: Arc::new(Mutex::new(None)),
|
|
|
|
shutdown: Arc::new(Mutex::new(None)),
|
|
|
|
restart_progress: Arc::new(Mutex::new(false)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-26 12:19:57 +08:00
|
|
|
pub async fn sql_get(&self) -> CustomResult<sql::Database> {
|
2024-11-28 23:10:00 +08:00
|
|
|
self.db.lock().await.clone().ok_or_else(|| "数据库未连接".into_custom_error())
|
2024-11-20 19:53:18 +08:00
|
|
|
}
|
|
|
|
|
2024-11-25 03:36:24 +08:00
|
|
|
pub async fn sql_link(&self, config: &config::SqlConfig) -> CustomResult<()> {
|
2024-11-26 12:19:57 +08:00
|
|
|
*self.db.lock().await = Some(sql::Database::link(config).await?);
|
2024-11-20 19:53:18 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
2024-11-18 01:09:28 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
|
2024-11-25 03:36:24 +08:00
|
|
|
pub async fn set_shutdown(&self, shutdown: Shutdown) {
|
|
|
|
*self.shutdown.lock().await = Some(shutdown);
|
|
|
|
}
|
2024-11-22 13:13:04 +08:00
|
|
|
|
2024-11-25 03:36:24 +08:00
|
|
|
pub async fn trigger_restart(&self) -> CustomResult<()> {
|
|
|
|
*self.restart_progress.lock().await = true;
|
2024-11-28 23:10:00 +08:00
|
|
|
self.shutdown.lock().await.take().ok_or_else(|| "未能获取rocket的shutdown".into_custom_error())?.notify();
|
2024-11-25 03:36:24 +08:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rocket::main]
|
|
|
|
async fn main() -> CustomResult<()> {
|
2024-11-28 23:10:00 +08:00
|
|
|
let config = config::Config::read().unwrap_or_else(|e| {
|
|
|
|
eprintln!("配置读取失败: {}", e);
|
|
|
|
config::Config::default()
|
|
|
|
});
|
2024-11-25 22:43:24 +08:00
|
|
|
let state = Arc::new(AppState::new());
|
2024-11-20 19:53:18 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
let rocket_config = rocket::Config::figment().merge(("address", config.address)).merge(("port", config.port));
|
2024-11-25 03:36:24 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
let mut rocket_builder = rocket::build().configure(rocket_config).manage(state.clone());
|
2024-11-25 03:36:24 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
if !config.init.sql {
|
|
|
|
rocket_builder = rocket_builder.mount("/", rocket::routes![api::setup::setup_sql]);
|
|
|
|
} else if !config.init.administrator {
|
|
|
|
rocket_builder = rocket_builder.mount("/", rocket::routes![api::setup::setup_account]);
|
2024-11-25 03:36:24 +08:00
|
|
|
} else {
|
2024-11-25 17:59:18 +08:00
|
|
|
state.sql_link(&config.sql_config).await?;
|
2024-11-28 23:10:00 +08:00
|
|
|
rocket_builder = rocket_builder.mount("/auth/token", api::jwt_routes()).mount("/config", api::configure_routes());
|
2024-11-25 22:43:24 +08:00
|
|
|
}
|
2024-11-25 03:36:24 +08:00
|
|
|
|
|
|
|
let rocket = rocket_builder.ignite().await?;
|
2024-11-20 19:53:18 +08:00
|
|
|
|
2024-11-28 23:10:00 +08:00
|
|
|
rocket.state::<Arc<AppState>>().ok_or_else(|| "未能获取AppState".into_custom_error())?.set_shutdown(rocket.shutdown()).await;
|
2024-11-25 03:36:24 +08:00
|
|
|
|
|
|
|
rocket.launch().await?;
|
|
|
|
|
2024-11-25 22:43:24 +08:00
|
|
|
if *state.restart_progress.lock().await {
|
|
|
|
if let Ok(current_exe) = std::env::current_exe() {
|
2024-11-28 23:10:00 +08:00
|
|
|
match std::process::Command::new(current_exe).spawn() {
|
|
|
|
Ok(_) => println!("成功启动新进程"),
|
|
|
|
Err(e) => eprintln!("启动新进程失败: {}", e),
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
eprintln!("获取当前可执行文件路径失败");
|
2024-11-25 22:43:24 +08:00
|
|
|
}
|
2024-11-25 03:36:24 +08:00
|
|
|
}
|
|
|
|
std::process::exit(0);
|
2024-11-21 01:04:59 +08:00
|
|
|
}
|