prefetch-npm-deps: read url bodies within the retry loop

This commit is contained in:
Lily Foster 2023-10-10 19:40:43 -04:00
parent a6df5a7719
commit 554e2412e0
No known key found for this signature in database
GPG key ID: 49340081E484C893
2 changed files with 22 additions and 20 deletions

View file

@ -4,7 +4,7 @@ use rayon::prelude::*;
use serde_json::{Map, Value}; use serde_json::{Map, Value};
use std::{ use std::{
fs, fs,
io::{self, Read}, io::Write,
process::{Command, Stdio}, process::{Command, Stdio},
}; };
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};
@ -106,7 +106,7 @@ impl Package {
let specifics = match get_hosted_git_url(&resolved)? { let specifics = match get_hosted_git_url(&resolved)? {
Some(hosted) => { Some(hosted) => {
let mut body = util::get_url_with_retry(&hosted)?; let body = util::get_url_body_with_retry(&hosted)?;
let workdir = tempdir()?; let workdir = tempdir()?;
@ -120,7 +120,7 @@ impl Package {
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.spawn()?; .spawn()?;
io::copy(&mut body, &mut cmd.stdin.take().unwrap())?; cmd.stdin.take().unwrap().write_all(&body)?;
let exit = cmd.wait()?; let exit = cmd.wait()?;
@ -154,13 +154,7 @@ impl Package {
pub fn tarball(&self) -> anyhow::Result<Vec<u8>> { pub fn tarball(&self) -> anyhow::Result<Vec<u8>> {
match &self.specifics { match &self.specifics {
Specifics::Registry { .. } => { Specifics::Registry { .. } => Ok(util::get_url_body_with_retry(&self.url)?),
let mut body = Vec::new();
util::get_url_with_retry(&self.url)?.read_to_end(&mut body)?;
Ok(body)
}
Specifics::Git { workdir } => Ok(Command::new("tar") Specifics::Git { workdir } => Ok(Command::new("tar")
.args([ .args([
"--sort=name", "--sort=name",

View file

@ -4,7 +4,7 @@ use isahc::{
Body, Request, RequestExt, Body, Request, RequestExt,
}; };
use serde_json::{Map, Value}; use serde_json::{Map, Value};
use std::{env, path::Path}; use std::{env, io::Read, path::Path};
use url::Url; use url::Url;
pub fn get_url(url: &Url) -> Result<Body, isahc::Error> { pub fn get_url(url: &Url) -> Result<Body, isahc::Error> {
@ -28,7 +28,7 @@ pub fn get_url(url: &Url) -> Result<Body, isahc::Error> {
if let Some(host) = url.host_str() { if let Some(host) = url.host_str() {
if let Ok(npm_tokens) = env::var("NIX_NPM_TOKENS") { if let Ok(npm_tokens) = env::var("NIX_NPM_TOKENS") {
if let Ok(tokens) = serde_json::from_str::<Map<String, Value>>(&npm_tokens) { if let Ok(tokens) = serde_json::from_str::<Map<String, Value>>(&npm_tokens) {
if let Some(token) = tokens.get(host).and_then(|val| val.as_str()) { if let Some(token) = tokens.get(host).and_then(serde_json::Value::as_str) {
request = request.header("Authorization", format!("Bearer {token}")); request = request.header("Authorization", format!("Bearer {token}"));
} }
} }
@ -38,15 +38,23 @@ pub fn get_url(url: &Url) -> Result<Body, isahc::Error> {
Ok(request.body(())?.send()?.into_body()) Ok(request.body(())?.send()?.into_body())
} }
pub fn get_url_with_retry(url: &Url) -> Result<Body, isahc::Error> { pub fn get_url_body_with_retry(url: &Url) -> Result<Vec<u8>, isahc::Error> {
retry(ExponentialBackoff::default(), || { retry(ExponentialBackoff::default(), || {
get_url(url).map_err(|err| { get_url(url)
if err.is_network() || err.is_timeout() { .and_then(|mut body| {
backoff::Error::transient(err) let mut buf = Vec::new();
} else {
backoff::Error::permanent(err) body.read_to_end(&mut buf)?;
}
}) Ok(buf)
})
.map_err(|err| {
if err.is_network() || err.is_timeout() {
backoff::Error::transient(err)
} else {
backoff::Error::permanent(err)
}
})
}) })
.map_err(|backoff_err| match backoff_err { .map_err(|backoff_err| match backoff_err {
backoff::Error::Permanent(err) backoff::Error::Permanent(err)