diff --git a/backend/api_server/Cargo.toml b/backend/api_server/Cargo.toml index bb2012c..09883f5 100644 --- a/backend/api_server/Cargo.toml +++ b/backend/api_server/Cargo.toml @@ -19,4 +19,5 @@ serde_json = "1.0.128" uuid = { version = "1.10.0", features = ["v4", "fast-rng", "serde"] } futures = { version = "0.3.30", features = ["executor"] } sha2 = "0.10.8" -cron = "0.12.1" \ No newline at end of file +cron = "0.12.1" +git2 = "0.19.0" diff --git a/backend/api_server/src/blog/cron/check_update.rs b/backend/api_server/src/blog/cron/check_update.rs new file mode 100644 index 0000000..f2fe6a9 --- /dev/null +++ b/backend/api_server/src/blog/cron/check_update.rs @@ -0,0 +1,24 @@ +use dirs::home_dir; +use std::env; + +pub fn task() { + // get dir + let git_work_dir_path = &env::var("GIT_WORK_DIR").unwrap_or_else(|e| { + if let Ok(default_log_path) = env::var("WORK_DIR") { + if default_log_path.starts_with('~') { + let home_path = home_dir().unwrap_or_else(|| panic!("Cannot find home directory")); + home_path + .join(default_log_path.strip_prefix("~/").unwrap()) + .into_os_string() + .into_string() + .expect( + "[fatal] failed to parse env `WORK_DIR`, try to use absolute path instead", + ) + } else { + default_log_path + } + } else { + panic!("[fatal] failed to parse env `GIT_WORK_DIR`: {}", e); + } + }); +} diff --git a/backend/api_server/src/blog/cron/mod.rs b/backend/api_server/src/blog/cron/mod.rs new file mode 100644 index 0000000..be1305e --- /dev/null +++ b/backend/api_server/src/blog/cron/mod.rs @@ -0,0 +1 @@ +pub mod check_update; diff --git a/backend/api_server/src/blog/mod.rs b/backend/api_server/src/blog/mod.rs index 06ac819..8b61780 100644 --- a/backend/api_server/src/blog/mod.rs +++ b/backend/api_server/src/blog/mod.rs @@ -1,4 +1,5 @@ mod api; +pub mod cron; use crate::blog::api::{ get_page_count::get_page_count, get_post::get_post, get_post_list::get_post_list, diff --git a/backend/api_server/src/init.rs b/backend/api_server/src/init.rs index 809b977..73e53fd 100644 --- a/backend/api_server/src/init.rs +++ b/backend/api_server/src/init.rs @@ -1,11 +1,17 @@ -use std::env; - use crate::logger; +use std::{ + backtrace::{Backtrace, BacktraceStatus}, + env, panic, + panic::PanicHookInfo, +}; +use tracing::{error, event, span, Level}; use tracing_appender::non_blocking::WorkerGuard; pub fn logger_init() -> (WorkerGuard, WorkerGuard) { - logger::init() + let ret = logger::init(); + panic::set_hook(Box::new(panic_hook)); + ret } pub fn load_env() { @@ -22,3 +28,29 @@ pub fn load_env() { println!("[info] no .env file referred, starting up") } } + +fn panic_hook(panic_info: &PanicHookInfo) { + let payload = panic_info.payload(); + // panic_info. + + let payload = if let Some(s) = payload.downcast_ref::<&str>() { + Some(&**s) + } else { + payload.downcast_ref::().map(|s| s.as_str()) + }; + + // let location = panic_info.location().map(|l| l.to_string()); + // let backtrace = Backtrace::capture(); + // let note = (backtrace.status() == BacktraceStatus::Disabled) + // .then_some("run with RUST_BACKTRACE=1 environment variable to display a backtrace"); + // (Some(backtrace), note) + // }; + // + // panic_info. + + if let Some(location) = panic_info.location() { + eprintln!("err filename: {}", location.file()) + } + + event!(target: "test", Level::ERROR, "panic hook: {:?}", panic_info); +} diff --git a/backend/api_server/src/main.rs b/backend/api_server/src/main.rs index 520be42..411e673 100644 --- a/backend/api_server/src/main.rs +++ b/backend/api_server/src/main.rs @@ -9,5 +9,12 @@ async fn main() { init::load_env(); let _guards = init::logger_init(); - server::start().await; + // panic!("test"); + + match server::start().await { + Ok(_) => {} + Err(e) => { + panic!("server start failed: {}", e); + } + }; } diff --git a/backend/api_server/src/scheduler/mod.rs b/backend/api_server/src/scheduler/mod.rs index 21678f4..08f018c 100644 --- a/backend/api_server/src/scheduler/mod.rs +++ b/backend/api_server/src/scheduler/mod.rs @@ -156,6 +156,10 @@ impl Scheduler { self.tasks.write()?.insert(id, Arc::new(task)); Ok(id) } + + pub fn new() -> Self { + Self::default() + } } #[cfg(test)] diff --git a/backend/api_server/src/scheduler/tasks/basic.rs b/backend/api_server/src/scheduler/tasks/basic.rs index 0318899..71fc3a6 100644 --- a/backend/api_server/src/scheduler/tasks/basic.rs +++ b/backend/api_server/src/scheduler/tasks/basic.rs @@ -11,12 +11,19 @@ pub struct BasicTask { } impl BasicTask { - pub fn new(func: fn(), cron_expr: &str) -> Result> { + pub fn new(func: F, cron_expr: &str) -> Result> + where + F: TaskFunc, + { Ok(BasicTask { schedule: Schedule::from_str(cron_expr)?, func: Box::new(func), }) } + + pub fn to_task(self) -> Box { + Box::new(self) + } } impl Task for BasicTask { diff --git a/backend/api_server/src/server.rs b/backend/api_server/src/server.rs index e23e63b..6dfb8e8 100644 --- a/backend/api_server/src/server.rs +++ b/backend/api_server/src/server.rs @@ -1,9 +1,12 @@ use std::env; +use std::error::Error; use std::num::ParseIntError; use std::process::exit; use std::str::FromStr; use crate::blog; +use crate::scheduler::tasks::basic::BasicTask; +use crate::scheduler::Scheduler; use axum::Router; use sqlx::{ postgres::{PgConnectOptions, PgPoolOptions}, @@ -11,7 +14,7 @@ use sqlx::{ }; use tracing::{error, info, warn}; -pub async fn start() { +pub async fn start() -> Result<(), Box> { let port: u32 = match env::var("BACKEND_PORT") { Ok(value) => value.parse().unwrap_or_else(|e: ParseIntError| { warn!("failed to parse BACKEND_PORT: {}", e.to_string()); @@ -35,6 +38,18 @@ pub async fn start() { } }; + // cron task + let scheduler = Scheduler::new(); + let test_str = "hello world".to_string(); + // scheduler.insert( + // BasicTask::new( + // move || blog::cron::check_update::task(test_str.clone()), + // "* * * * * *", + // )? + // .to_task(), + // )?; + + // http server let app = Router::new() .nest("blog", blog::get_router()) .with_state(db_pool); @@ -50,6 +65,7 @@ pub async fn start() { error!("failed to start axum: {}", e.to_string()); exit(1); }); + Ok(()) } fn parse_db_uri() -> String { diff --git a/backend/markdown/Cargo.toml b/backend/markdown/Cargo.toml index 896c0c8..0d0b372 100644 --- a/backend/markdown/Cargo.toml +++ b/backend/markdown/Cargo.toml @@ -9,6 +9,6 @@ chrono = { version = "0.4.38", features = ["serde", "alloc"] } serde = { version = "1.0.209", features = ["derive"] } serde_json = "1.0.128" regex = "1.10.4" -yaml-rust2 = "0.8.1" +yaml-rust2 = "0.9.0" sha2 = "0.10.8" base64 = "0.22.1" diff --git a/backend/markdown/src/utils/front_matter.rs b/backend/markdown/src/utils/front_matter.rs index 5bca291..f38f029 100644 --- a/backend/markdown/src/utils/front_matter.rs +++ b/backend/markdown/src/utils/front_matter.rs @@ -60,7 +60,7 @@ tags: [ "test1", "test2" ] #[test] fn test_front_matter_parser() { - parse_front_matter( + dbg!(parse_front_matter( r##"--- title: test_title date: 0000-00-00+0000 @@ -71,7 +71,7 @@ summary: summary tags: [ "test1", "test2" ] --- "##, - ) + )) .expect("Failed to parse front matter"); } }