diff --git a/src/cache/menu_cache.rs b/src/cache/menu_cache.rs index ae1df88..2ae159a 100644 --- a/src/cache/menu_cache.rs +++ b/src/cache/menu_cache.rs @@ -7,6 +7,7 @@ use crate::{ use chrono::{DateTime, Utc}; use firestore::FirestoreDb; use futures::{stream::FuturesUnordered, StreamExt}; +use log::info; use tokio::io::AsyncReadExt; const CACHES_COLLECTION: &str = "caches"; @@ -23,6 +24,8 @@ struct InDbMenuCache { data: Vec, } +pub static REFRESH_INTERVAL: chrono::Duration = chrono::Duration::minutes(15); + impl<'a> MenuCache<'a> { async fn from_async(cache: InDbMenuCache) -> Self { if cache.data.is_empty() { @@ -31,10 +34,15 @@ impl<'a> MenuCache<'a> { locations: Locations::default(), }; } - let mut uncompressed = + let mut decompress = async_compression::tokio::bufread::GzipDecoder::new(cache.data.as_slice()); + info!("Size of data compressed: {}", cache.data.len()); let mut dst = String::with_capacity(cache.data.len() * 8); - uncompressed.read_to_string(&mut dst).await; + let _len = decompress + .read_to_string(&mut dst) + .await + .expect("should succeed"); + info!("Size of data uncompressed: {}", dst.len()); let locations: Locations = serde_json::from_str(&dst).expect("Data parse should always be valid"); MenuCache { @@ -59,7 +67,7 @@ impl<'a> MenuCache<'a> { } pub async fn maybe_refresh(&mut self) -> Result { - if Utc::now().signed_duration_since(self.cached_at) > chrono::Duration::minutes(15) { + if self.get_time_since_refresh() > chrono::Duration::minutes(15) { self.refresh().await?; Ok(true) } else { @@ -67,6 +75,14 @@ impl<'a> MenuCache<'a> { } } + pub fn get_time_since_refresh(&self) -> chrono::Duration { + Utc::now().signed_duration_since(self.cached_at) + } + + pub fn get_time_until_refresh(&self) -> chrono::Duration { + REFRESH_INTERVAL - self.get_time_since_refresh() + } + async fn fetch_from_db() -> Result { let db = FirestoreDb::new("ucsc-menu").await?; let cache: InDbMenuCache = db @@ -158,6 +174,7 @@ mod tests { #[tokio::test] async fn test_open() { + pretty_env_logger::init(); let _mc = MenuCache::open().await.unwrap(); } diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 287b336..541dff8 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -1,4 +1,5 @@ mod menu_cache; mod multithreaded_cache; +pub use menu_cache::REFRESH_INTERVAL; pub use multithreaded_cache::MultithreadedCache as Multithreaded; diff --git a/src/main.rs b/src/main.rs index 5e099f9..a972eed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,13 @@ mod fetch; mod parse; mod transpose; -use std::{env, net::SocketAddr, str::FromStr, sync::Arc, time::Duration}; +use std::{ + env, + net::SocketAddr, + str::FromStr, + sync::Arc, + time::{Duration, Instant}, +}; use axum::{ body::Body, @@ -63,9 +69,14 @@ async fn refresh<'a>() -> Response { .get_or_init(|| async { Multithreaded::new().await.unwrap() }) .await; let _res = cache.refresh().await; + let c = cache.get().await; Response::builder() .status(201) - .body(Body::from("OK")) + .body(Body::from(format!( + "Last refresh: {}\nNext refresh: {}", + c.get_time_since_refresh(), + c.get_time_until_refresh(), + ))) .unwrap() } @@ -83,7 +94,7 @@ async fn main() { .deflate(true) .gzip(true) .zstd(true); - pretty_env_logger::init_custom_env("ucsc_menu=info"); + pretty_env_logger::init(); let app = Router::new() .route( @@ -105,12 +116,19 @@ async fn main() { tokio::spawn(async move { let client = make_client(); log::info!("Forcing refresh"); + let start = Instant::now(); let _res = client .put(format!("http://{addr}/request-refresh")) .send() .await; - log::info!("Forcing refresh done"); - sleep(Duration::from_secs(15 * 60)).await; + log::info!("Forcing refresh done, took {:?}", start.elapsed()); + sleep(Duration::from_secs( + cache::REFRESH_INTERVAL + .num_seconds() + .try_into() + .expect("refresh interval to be positive"), + )) + .await; }); let listener = TcpListener::bind(addr) .await