Skip to content

Commit 605f13c

Browse files
committed
add offline caches
1 parent 994915e commit 605f13c

File tree

3 files changed

+72
-15
lines changed

3 files changed

+72
-15
lines changed

compiler-cli/src/dependencies.rs

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
mod dependency_manager;
22

33
use std::{
4-
cell::RefCell,
5-
collections::{HashMap, HashSet},
6-
process::Command,
7-
rc::Rc,
8-
time::Instant,
4+
cell::RefCell, collections::{HashMap, HashSet}, io::Read, process::Command, rc::Rc, time::Instant
95
};
106

117
use camino::{Utf8Path, Utf8PathBuf};
128
use ecow::{EcoString, eco_format};
139
use flate2::read::GzDecoder;
1410
use gleam_core::{
15-
Error, Result,
1611
build::{Mode, Target, Telemetry},
1712
config::PackageConfig,
1813
dependency::{self, PackageFetchError},
@@ -22,6 +17,9 @@ use gleam_core::{
2217
manifest::{Base16Checksum, Manifest, ManifestPackage, ManifestPackageSource, Resolved},
2318
paths::ProjectPaths,
2419
requirement::Requirement,
20+
io::{ FileSystemReader, FileSystemWriter, HttpClient as _,},
21+
paths::{global_hexpm_package_release_response_cache, global_hexpm_packages_response_cache},
22+
Error, Result
2523
};
2624
use hexpm::version::Version;
2725
use itertools::Itertools;
@@ -34,11 +32,7 @@ pub use dependency_manager::DependencyManagerConfig;
3432
mod tests;
3533

3634
use crate::{
37-
TreeOptions,
38-
build_lock::{BuildLock, Guard},
39-
cli,
40-
fs::{self, ProjectIO},
41-
http::HttpClient,
35+
build_lock::{BuildLock, Guard}, cli, fs::{self, ProjectIO}, http::HttpClient, TreeOptions
4236
};
4337

4438
struct Symbols {
@@ -1093,8 +1087,37 @@ async fn lookup_package(
10931087
Some(provided_package) => Ok(provided_package.to_manifest_package(name.as_str())),
10941088
None => {
10951089
let config = hexpm::Config::new();
1090+
// performance may be able to be improved by reading from local cache first
1091+
// depending on the volatility of the endpoint
1092+
// retirement status volatile, content volatile one hour after initial publication
1093+
// content may be edited or deleted by admins
1094+
let mut resp_body = Vec::new();
10961095
let release =
1097-
hex::get_package_release(&name, &version, &config, &HttpClient::new()).await?;
1096+
hex::get_package_release(&name, &version, &config, Some(&mut resp_body), &HttpClient::new()).await;
1097+
let fs = ProjectIO::new();
1098+
let cache_path = global_hexpm_package_release_response_cache(&name, &version.to_string());
1099+
let release = match release {
1100+
Ok(rel) => {
1101+
// save
1102+
// FIXME: I may not need to wright every time
1103+
let _ = fs.write_bytes(&cache_path, &resp_body);
1104+
rel
1105+
},
1106+
Err(_) => {
1107+
// load
1108+
let cached_result = fs.read_bytes(&cache_path)
1109+
.map_err(|err| Error::FileIo {
1110+
action: FileIoAction::Read,
1111+
kind: FileKind::File,
1112+
path: cache_path,
1113+
err: Some(err.to_string()),
1114+
})?;
1115+
1116+
// FIXME: I crash when the cache is bad
1117+
// author note
1118+
serde_json::from_slice(&cached_result).expect("cache bad")
1119+
}
1120+
};
10981121
let build_tools = release
10991122
.meta
11001123
.build_tools
@@ -1187,10 +1210,28 @@ impl dependency::PackageFetcher for PackageFetcher {
11871210
let response = self
11881211
.runtime
11891212
.block_on(self.http.send(request))
1190-
.map_err(PackageFetchError::fetch_error)?;
1213+
.map_err(PackageFetchError::fetch_error);
1214+
1215+
let fs = ProjectIO::new();
1216+
let cache_path = &global_hexpm_packages_response_cache(package);
1217+
let pkg = match response {
1218+
Ok(resp) => {
1219+
tracing::debug!(package = package, "saving_hex_package");
1220+
let _ = fs.write_bytes(cache_path, resp.body());
1221+
hexpm::get_package_response(resp, HEXPM_PUBLIC_KEY)
1222+
},
1223+
Err(_err) => {
1224+
tracing::debug!(package = package, "fetching_package_data_from_cache");
1225+
let reader = fs.reader(cache_path)
1226+
.map_err(PackageFetchError::fetch_error)?;
1227+
let mut decoder = GzDecoder::new(reader);
1228+
let mut data = Vec::new();
1229+
let _ = decoder.read_to_end(&mut data)
1230+
.map_err(PackageFetchError::fetch_error)?;
1231+
hexpm::get_package_data(&data, HEXPM_PUBLIC_KEY)
1232+
},
1233+
}.map_err(PackageFetchError::from)?;
11911234

1192-
let pkg = hexpm::get_package_response(response, HEXPM_PUBLIC_KEY)
1193-
.map_err(PackageFetchError::from)?;
11941235
let pkg = Rc::new(pkg);
11951236
let pkg_ref = Rc::clone(&pkg);
11961237
self.cache_package(package, pkg);

compiler-core/src/hex.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ pub async fn get_package_release<Http: HttpClient>(
294294
name: &str,
295295
version: &Version,
296296
config: &hexpm::Config,
297+
raw_response: Option<&mut Vec<u8>>,
297298
http: &Http,
298299
) -> Result<hexpm::Release<hexpm::ReleaseMeta>> {
299300
let version = version.to_string();
@@ -304,5 +305,8 @@ pub async fn get_package_release<Http: HttpClient>(
304305
);
305306
let request = hexpm::get_package_release_request(name, &version, None, config);
306307
let response = http.send(request).await?;
308+
if let Some(data) = raw_response {
309+
data.clone_from(response.body());
310+
}
307311
hexpm::get_package_release_response(response).map_err(Error::hex)
308312
}

compiler-core/src/paths.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ pub fn global_package_cache_package_tarball(package_name: &str, version: &str) -
130130
global_packages_cache().join(format!("{package_name}-{version}.tar"))
131131
}
132132

133+
pub fn global_hexpm_packages_response_cache(package_name: &str) -> Utf8PathBuf {
134+
global_hexpm_response_cache_path().join(format!("packages-{package_name}.gz"))
135+
}
136+
137+
pub fn global_hexpm_package_release_response_cache(package_name: &str, version: &str) -> Utf8PathBuf {
138+
global_hexpm_response_cache_path().join(format!("packages-{package_name}-releases-{version}.json"))
139+
}
140+
141+
fn global_hexpm_response_cache_path() -> Utf8PathBuf {
142+
global_hexpm_cache().join("response")
143+
}
144+
133145
pub fn global_hexpm_credentials_path() -> Utf8PathBuf {
134146
global_hexpm_cache().join("credentials")
135147
}

0 commit comments

Comments
 (0)