Implement negative caching for narinfo

Fixes #4.
This commit is contained in:
Zhaofeng Li 2023-05-19 13:00:36 -06:00
parent 1c623c091c
commit ec04905db4
2 changed files with 32 additions and 6 deletions

View file

@ -50,15 +50,23 @@ async fn get_narinfo(
let store_path_hash = components[0].to_string(); let store_path_hash = components[0].to_string();
let key = format!("{}.narinfo", store_path_hash); let key = format!("{}.narinfo", store_path_hash);
if state
.narinfo_nagative_cache
.read()
.await
.contains(&store_path_hash)
{
return pull_through(&state, &path);
}
if let Some(url) = state.api.get_file_url(&[&key]).await? { if let Some(url) = state.api.get_file_url(&[&key]).await? {
return Ok(Redirect::temporary(&url)); return Ok(Redirect::temporary(&url));
} }
if let Some(upstream) = &state.upstream { let mut negative_cache = state.narinfo_nagative_cache.write().await;
Ok(Redirect::temporary(&format!("{}/{}", upstream, path))) negative_cache.insert(store_path_hash);
} else {
Err(Error::NotFound) pull_through(&state, &path)
}
} }
async fn put_narinfo( async fn put_narinfo(
Extension(state): Extension<State>, Extension(state): Extension<State>,
@ -83,6 +91,12 @@ async fn put_narinfo(
); );
state.api.upload_file(allocation, stream).await?; state.api.upload_file(allocation, stream).await?;
state
.narinfo_nagative_cache
.write()
.await
.remove(&store_path_hash);
Ok(()) Ok(())
} }
@ -110,3 +124,11 @@ async fn put_nar(
Ok(()) Ok(())
} }
fn pull_through(state: &State, path: &str) -> Result<Redirect> {
if let Some(upstream) = &state.upstream {
Ok(Redirect::temporary(&format!("{}/{}", upstream, path)))
} else {
Err(Error::NotFound)
}
}

View file

@ -30,7 +30,7 @@ use clap::Parser;
use daemonize::Daemonize; use daemonize::Daemonize;
use tokio::{ use tokio::{
runtime::Runtime, runtime::Runtime,
sync::{oneshot, Mutex}, sync::{oneshot, Mutex, RwLock},
}; };
use tracing_subscriber::filter::EnvFilter; use tracing_subscriber::filter::EnvFilter;
@ -89,6 +89,9 @@ struct StateInner {
/// List of store paths originally present. /// List of store paths originally present.
original_paths: Mutex<HashSet<PathBuf>>, original_paths: Mutex<HashSet<PathBuf>>,
/// Set of store path hashes that are not present in GHAC.
narinfo_nagative_cache: RwLock<HashSet<String>>,
} }
fn main() { fn main() {
@ -120,6 +123,7 @@ fn main() {
upstream: args.upstream.clone(), upstream: args.upstream.clone(),
shutdown_sender: Mutex::new(Some(shutdown_sender)), shutdown_sender: Mutex::new(Some(shutdown_sender)),
original_paths: Mutex::new(HashSet::new()), original_paths: Mutex::new(HashSet::new()),
narinfo_nagative_cache: RwLock::new(HashSet::new()),
}); });
let app = Router::new() let app = Router::new()