From 300e9eb7261fda84cb548ffeed84330acdaf64f1 Mon Sep 17 00:00:00 2001 From: Andho Mohamed Date: Fri, 6 Dec 2024 20:19:15 +0500 Subject: [PATCH] feat(dependencies): cache package info from hexpm to reduce duplicate calls :sparkles: --- compiler-cli/src/dependencies.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler-cli/src/dependencies.rs b/compiler-cli/src/dependencies.rs index 0ee12e7aba5..07ed4ecc6b4 100644 --- a/compiler-cli/src/dependencies.rs +++ b/compiler-cli/src/dependencies.rs @@ -1,4 +1,5 @@ use std::{ + cell::RefCell, collections::{HashMap, HashSet}, time::Instant, }; @@ -959,6 +960,7 @@ async fn lookup_package( } struct PackageFetcher { + runtime_cache: RefCell>, runtime: tokio::runtime::Handle, http: HttpClient, } @@ -966,10 +968,19 @@ struct PackageFetcher { impl PackageFetcher { pub fn boxed(runtime: tokio::runtime::Handle) -> Box { 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)] @@ -1003,6 +1014,15 @@ impl dependency::PackageFetcher for PackageFetcher { &self, package: &str, ) -> Result> { + { + 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); @@ -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())