diff --git a/src/main.rs b/src/main.rs index dfa8cdb..91b3ce8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,32 +27,14 @@ mod user; mod version_update; mod ping; -#[tokio::main] -async fn main() -> Result<()> { - let config = init::init_config()?; - - let server_log_folder_path = config.server_log_folder_path.clone(); - - let app_data = web::Data::new(AppData { - server_data_folder_path: config.server_data_folder_path, - rwr_profile_folder_path: config.rwr_profile_folder_path, - server_log_folder_path: config.server_log_folder_path, - server_upload_temp_folder_path: config.server_upload_temp_folder_path, - user_json_lock: Mutex::new(0), - // hourly query_all - snapshot_data: Mutex::new(vec![]), - snapshot_str: Mutex::new(String::new()), - snapshot_time: Mutex::new(String::new()), - // ranks snapshot - snapshot_ranks: Mutex::new(vec![]), - }); - +/// Initialize the logging system with both console and file output if configured +fn setup_logging(server_log_folder_path: &str) { let std_out_layer = tracing_subscriber::fmt::layer() .pretty() .with_filter(LevelFilter::INFO); if !server_log_folder_path.is_empty() { - let file_appender = rolling::daily(&server_log_folder_path, "info.log"); + let file_appender = rolling::daily(server_log_folder_path, "info.log"); let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); let fmt_layer = tracing_subscriber::fmt::layer() @@ -69,52 +51,64 @@ async fn main() -> Result<()> { .with(std_out_layer) .init(); } +} - info!("completed reading app_data: {:?}", app_data); +/// Create and initialize the application state +fn create_app_data(config: &model::Config) -> web::Data { + web::Data::new(AppData { + server_data_folder_path: config.server_data_folder_path.clone(), + rwr_profile_folder_path: config.rwr_profile_folder_path.clone(), + server_log_folder_path: config.server_log_folder_path.clone(), + server_upload_temp_folder_path: config.server_upload_temp_folder_path.clone(), + user_json_lock: Mutex::new(0), + snapshot_data: Mutex::new(vec![]), + snapshot_str: Mutex::new(String::new()), + snapshot_time: Mutex::new(String::new()), + snapshot_ranks: Mutex::new(vec![]), + }) +} +/// Setup the background task for hourly data updates +async fn setup_hourly_updates(app_data: web::Data) { let app_data_c = app_data.clone(); + + tokio::task::spawn(async move { + let mut interval = interval(Duration::from_secs(60 * 60)); + + loop { + interval.tick().await; + update_snapshot_data(&app_data_c).await; + } + }); +} - // update file version - let folder_path = app_data_c.rwr_profile_folder_path.clone(); - preupdate(folder_path).await?; +/// Update the snapshot data in the application state +async fn update_snapshot_data(app_data: &web::Data) { + let folder_path = app_data.rwr_profile_folder_path.clone(); - if config.server_hourly_request { - tokio::task::spawn(async move { - // 1 hour interval - let mut interval = interval(Duration::from_secs(60 * 60)); - - loop { - interval.tick().await; - - let folder_path = app_data_c.rwr_profile_folder_path.clone(); - - match async_extract_query_data(folder_path).await { - Ok(all_person_and_profiles_list) => { - info!("query all peron res {:?}", all_person_and_profiles_list); - - let mut snapshot_data = app_data_c.snapshot_data.lock().await; - *snapshot_data = all_person_and_profiles_list.clone(); - - let mut snapshot_str = app_data_c.snapshot_str.lock().await; - *snapshot_str = - serde_json::to_string(&all_person_and_profiles_list).unwrap(); - - // TODO: next release - // fs::write("demo2_json.json", &*snapshot_str).await.unwrap(); - - let local = Local::now(); - let current_time = local.format("%Y-%m-%d %H:%M:%S").to_string(); - let mut snapshot_time = app_data_c.snapshot_time.lock().await; - *snapshot_time = current_time; - } - Err(err) => { - error!("query all person error: {:?}", err); - } - } - } - }); + match async_extract_query_data(folder_path).await { + Ok(all_person_and_profiles_list) => { + info!("query all person res {:?}", all_person_and_profiles_list); + + let mut snapshot_data = app_data.snapshot_data.lock().await; + *snapshot_data = all_person_and_profiles_list.clone(); + + let mut snapshot_str = app_data.snapshot_str.lock().await; + *snapshot_str = serde_json::to_string(&all_person_and_profiles_list).unwrap(); + + let local = Local::now(); + let current_time = local.format("%Y-%m-%d %H:%M:%S").to_string(); + let mut snapshot_time = app_data.snapshot_time.lock().await; + *snapshot_time = current_time; + } + Err(err) => { + error!("query all person error: {:?}", err); + } } +} +/// Configure and start the HTTP server +async fn run_server(app_data: web::Data, port: u16) -> Result<()> { HttpServer::new(move || { App::new() .app_data(web::Data::clone(&app_data)) @@ -124,8 +118,32 @@ async fn main() -> Result<()> { .configure(system_config) .configure(ping::ping_config) }) - .bind(format!("0.0.0.0:{}", config.port))? + .bind(format!("0.0.0.0:{}", port))? .run() .await .map_err(Error::msg) } + +#[tokio::main] +async fn main() -> Result<()> { + // Initialize configuration + let config = init::init_config()?; + + // Setup logging + setup_logging(&config.server_log_folder_path); + + // Create application state + let app_data = create_app_data(&config); + info!("completed reading app_data: {:?}", app_data); + + // Update file version + preupdate(app_data.rwr_profile_folder_path.clone()).await?; + + // Setup background tasks if enabled + if config.server_hourly_request { + setup_hourly_updates(app_data.clone()).await; + } + + // Start the server + run_server(app_data, config.port.try_into().unwrap()).await +}