parent
1c623c091c
commit
ec04905db4
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue