This commit is contained in:
2025-06-27 20:30:40 +02:00
parent 8463edd262
commit a843208422
4 changed files with 192 additions and 2 deletions

View File

@@ -1,3 +1,4 @@
#[warn(unused_imports)]
use clap::{Parser, Subcommand};
mod markdown;
use markdown::{get_all_posts, get_post_by_slug, get_posts_by_tag, watch_posts};
@@ -28,6 +29,8 @@ enum Commands {
Watch,
/// Show Rust parser statistics
Rsparseinfo,
/// Check backend health
Checkhealth,
}
fn main() {
@@ -73,5 +76,9 @@ fn main() {
Commands::Rsparseinfo => {
println!("{}", markdown::rsparseinfo());
}
Commands::Checkhealth => {
let health = markdown::checkhealth();
println!("{}", serde_json::to_string_pretty(&health).unwrap());
}
}
}

View File

@@ -8,7 +8,7 @@ BLAZINGLY FAST!
*/
#[warn(unused_imports)]
use std::fs;
use std::path::{Path, PathBuf};
use chrono::{DateTime, Utc};
@@ -29,6 +29,7 @@ use std::collections::HashMap;
use std::sync::RwLock;
use serde_json;
use sysinfo::{System, Pid, RefreshKind, CpuRefreshKind, ProcessRefreshKind};
use serde::Serialize;
const POSTS_CACHE_PATH: &str = "./cache/posts_cache.json";
const POST_STATS_PATH: &str = "./cache/post_stats.json";
@@ -68,6 +69,19 @@ static POST_CACHE: Lazy<RwLock<HashMap<String, Post>>> = Lazy::new(|| RwLock::ne
static ALL_POSTS_CACHE: Lazy<RwLock<Option<Vec<Post>>>> = Lazy::new(|| RwLock::new(None));
static POST_STATS: Lazy<RwLock<HashMap<String, PostStats>>> = Lazy::new(|| RwLock::new(HashMap::new()));
#[derive(Debug, Serialize)]
pub struct HealthReport {
pub posts_dir_exists: bool,
pub posts_count: usize,
pub cache_file_exists: bool,
pub cache_stats_file_exists: bool,
pub cache_readable: bool,
pub cache_stats_readable: bool,
pub cache_post_count: Option<usize>,
pub cache_stats_count: Option<usize>,
pub errors: Vec<String>,
}
fn get_posts_directory() -> PathBuf {
let candidates = [
"./posts",
@@ -439,4 +453,66 @@ pub fn save_post_cache_to_disk() {
let _ = fs::create_dir_all("./cache");
let _ = fs::write(POST_STATS_PATH, map);
}
}
pub fn checkhealth() -> HealthReport {
let mut errors = Vec::new();
let posts_dir = get_posts_directory();
let posts_dir_exists = posts_dir.exists() && posts_dir.is_dir();
let mut posts_count = 0;
if posts_dir_exists {
match std::fs::read_dir(&posts_dir) {
Ok(entries) => {
posts_count = entries.filter_map(|e| e.ok())
.filter(|e| e.path().extension().map(|ext| ext == "md").unwrap_or(false))
.count();
},
Err(e) => errors.push(format!("Failed to read posts dir: {}", e)),
}
} else {
errors.push("Posts directory does not exist".to_string());
}
let cache_file_exists = Path::new(POSTS_CACHE_PATH).exists();
let cache_stats_file_exists = Path::new(POST_STATS_PATH).exists();
let (mut cache_readable, mut cache_post_count) = (false, None);
if cache_file_exists {
match std::fs::read_to_string(POSTS_CACHE_PATH) {
Ok(data) => {
match serde_json::from_str::<HashMap<String, Post>>(&data) {
Ok(map) => {
cache_readable = true;
cache_post_count = Some(map.len());
},
Err(e) => errors.push(format!("Cache file not valid JSON: {}", e)),
}
},
Err(e) => errors.push(format!("Failed to read cache file: {}", e)),
}
}
let (mut cache_stats_readable, mut cache_stats_count) = (false, None);
if cache_stats_file_exists {
match std::fs::read_to_string(POST_STATS_PATH) {
Ok(data) => {
match serde_json::from_str::<HashMap<String, PostStats>>(&data) {
Ok(map) => {
cache_stats_readable = true;
cache_stats_count = Some(map.len());
},
Err(e) => errors.push(format!("Cache stats file not valid JSON: {}", e)),
}
},
Err(e) => errors.push(format!("Failed to read cache stats file: {}", e)),
}
}
HealthReport {
posts_dir_exists,
posts_count,
cache_file_exists,
cache_stats_file_exists,
cache_readable,
cache_stats_readable,
cache_post_count,
cache_stats_count,
errors,
}
}