diff --git a/src/main.rs b/src/main.rs index 12d957b..5501830 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,12 +58,12 @@ async fn main() -> eyre::Result<()> { let posts = Arc::new(PostManager::new(Arc::clone(&config)).await?); let state = AppState { config: Arc::clone(&config), - posts, + posts: Arc::clone(&posts), }; if config.cache.enable && config.cache.cleanup { if let Some(t) = config.cache.cleanup_interval { - let state = state.clone(); + let posts = Arc::clone(&posts); let token = cancellation_token.child_token(); debug!("setting up cleanup task"); tasks.spawn(async move { @@ -72,13 +72,13 @@ async fn main() -> eyre::Result<()> { select! { _ = token.cancelled() => break, _ = interval.tick() => { - state.posts.cleanup().await + posts.cleanup().await } } } }); } else { - state.posts.cleanup().await; + posts.cleanup().await; } } diff --git a/src/post/mod.rs b/src/post/mod.rs index 99bef21..388fdd4 100644 --- a/src/post/mod.rs +++ b/src/post/mod.rs @@ -15,10 +15,10 @@ use tokio::io::AsyncReadExt; use tracing::{error, info, warn}; use crate::config::Config; +use crate::error::PostError; use crate::markdown_render::render; use crate::post::cache::{Cache, CACHE_VERSION}; use crate::systemtime_as_secs::as_secs; -use crate::PostError; #[derive(Deserialize)] struct FrontMatter { @@ -71,6 +71,32 @@ pub enum RenderStats { ParsedAndRendered(Duration, Duration, Duration), } +async fn load_cache(config: &Config) -> Result { + let path = &config.cache.file; + let mut cache_file = tokio::fs::File::open(&path) + .await + .context("failed to open cache file")?; + let serialized = if config.cache.compress { + let cache_file = cache_file.into_std().await; + tokio::task::spawn_blocking(move || { + let mut buf = Vec::with_capacity(4096); + zstd::stream::read::Decoder::new(cache_file)?.read_to_end(&mut buf)?; + Ok::<_, std::io::Error>(buf) + }) + .await? + .context("failed to read cache file")? + } else { + let mut buf = Vec::with_capacity(4096); + cache_file + .read_to_end(&mut buf) + .await + .context("failed to read cache file")?; + buf + }; + + bitcode::deserialize(serialized.as_slice()).context("failed to parse cache") +} + pub struct PostManager where C: Deref, @@ -85,57 +111,21 @@ where { pub async fn new(config: C) -> eyre::Result> { if config.cache.enable { - if config.cache.persistence - && tokio::fs::try_exists(&config.cache.file) - .await - .with_context(|| { - format!("failed to check if {} exists", config.cache.file.display()) - })? - { + if config.cache.persistence && tokio::fs::try_exists(&config.cache.file).await? { info!("loading cache from file"); - let path = &config.cache.file; - let load_cache = async { - let mut cache_file = tokio::fs::File::open(&path) - .await - .context("failed to open cache file")?; - let serialized = if config.cache.compress { - let cache_file = cache_file.into_std().await; - tokio::task::spawn_blocking(move || { - let mut buf = Vec::with_capacity(4096); - zstd::stream::read::Decoder::new(cache_file)?.read_to_end(&mut buf)?; - Ok::<_, std::io::Error>(buf) - }) - .await - .context("failed to join blocking thread")? - .context("failed to read cache file")? - } else { - let mut buf = Vec::with_capacity(4096); - cache_file - .read_to_end(&mut buf) - .await - .context("failed to read cache file")?; - buf - }; - let mut cache: Cache = bitcode::deserialize(serialized.as_slice()) - .context("failed to parse cache")?; - if cache.version() < CACHE_VERSION { - warn!("cache version changed, clearing cache"); - cache = Cache::default(); - }; + let mut cache = load_cache(&config).await.unwrap_or_else(|err| { + error!("failed to load cache: {}", err); + info!("using empty cache"); + Default::default() + }); - Ok::(cache) - } - .await; + if cache.version() < CACHE_VERSION { + warn!("cache version changed, clearing cache"); + cache = Default::default(); + }; Ok(Self { - cache: Some(match load_cache { - Ok(cache) => cache, - Err(err) => { - error!("failed to load cache: {}", err); - info!("using empty cache"); - Default::default() - } - }), + cache: Some(cache), config, }) } else {