Skip to content

Commit

Permalink
feat(dependencies): cache package info from hexpm to reduce duplicate…
Browse files Browse the repository at this point in the history
… calls ✨
  • Loading branch information
andho committed Dec 6, 2024
1 parent 6046de5 commit 300e9eb
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion compiler-cli/src/dependencies.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
cell::RefCell,
collections::{HashMap, HashSet},
time::Instant,
};
Expand Down Expand Up @@ -959,17 +960,27 @@ async fn lookup_package(
}

struct PackageFetcher {
runtime_cache: RefCell<HashMap<String, hexpm::Package>>,
runtime: tokio::runtime::Handle,
http: HttpClient,
}

impl PackageFetcher {
pub fn boxed(runtime: tokio::runtime::Handle) -> Box<Self> {
Box::new(Self {
runtime_cache: RefCell::new(HashMap::new()),
runtime,
http: HttpClient::new(),
})
}

/// Caches the result so subsequent calls to `get_dependencies` so that we don't need to make a
/// network request. Currently dependencies are fetched during initial version resolution, and
/// then during check for major version availability.
fn cache_package(&self, package: &str, result: hexpm::Package) {
let mut runtime_cache = self.runtime_cache.borrow_mut();
let _ = runtime_cache.insert(package.to_string(), result);
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -1003,6 +1014,15 @@ impl dependency::PackageFetcher for PackageFetcher {
&self,
package: &str,
) -> Result<hexpm::Package, Box<dyn std::error::Error>> {
{
let runtime_cache = self.runtime_cache.borrow();
let result = runtime_cache.get(package);

if let Some(result) = result {
return Ok(result.clone());
}
}

tracing::debug!(package = package, "looking_up_hex_package");
let config = hexpm::Config::new();
let request = hexpm::get_package_request(package, None, &config);
Expand All @@ -1012,7 +1032,10 @@ impl dependency::PackageFetcher for PackageFetcher {
.map_err(Box::new)?;

match hexpm::get_package_response(response, HEXPM_PUBLIC_KEY) {
Ok(a) => Ok(a),
Ok(a) => {
self.cache_package(package, a.clone());
Ok(a)
}
Err(e) => match e {
hexpm::ApiError::NotFound => {
Err(format!("I couldn't find a package called `{}`", package).into())
Expand Down

0 comments on commit 300e9eb

Please sign in to comment.