Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/dist/component/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::mem;
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::time::{Duration, Instant};

use anyhow::{Context, Result, anyhow, bail};
use tar::EntryType;
Expand Down Expand Up @@ -88,7 +89,7 @@ impl<P: Deref<Target = Path>> DirectoryPackage<P> {
}
}

pub fn install<'a>(
pub async fn install<'a>(
&self,
target: &Components,
name: &str,
Expand All @@ -108,7 +109,15 @@ impl<P: Deref<Target = Path>> DirectoryPackage<P> {
let manifest = utils::read_file("package manifest", &root.join("manifest.in"))?;
let mut builder = target.add(name, tx);

let yield_timeout = Duration::from_millis(50);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty short -- have you tried with longer intervals, like 250/500/1000ms?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No significant changes on my side with either of those values: the installation is always ~2x slower than latest.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that seems very surprising.

let mut last_yield = Instant::now();
for l in manifest.lines() {
if Instant::now().duration_since(last_yield) > yield_timeout {
// Yield to the async runtime to keep things moving
tokio::task::yield_now().await;
last_yield = Instant::now();
}

let part = ComponentPart::decode(l)
.ok_or_else(|| RustupError::CorruptComponent(name.to_owned()))?;

Expand Down
22 changes: 13 additions & 9 deletions src/dist/manifestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl Manifestation {

if let Some((bin, downloaded)) = installable {
cleanup_downloads.push(&bin.binary.hash);
tx = bin.install(downloaded, tx, self)?;
tx = bin.install(downloaded, tx, self).await?;
}
}

Expand Down Expand Up @@ -410,7 +410,9 @@ impl Manifestation {
let reader = utils::FileReaderWithProgress::new_file(&installer_file)?;
let package = DirectoryPackage::compressed(reader, CompressionKind::GZip, dl_cfg)?;
for component in package.components() {
tx = package.install(&self.installation, &component, None, tx)?;
tx = package
.install(&self.installation, &component, None, tx)
.await?;
}

// End transaction
Expand Down Expand Up @@ -705,7 +707,7 @@ impl<'a> ComponentBinary<'a> {
Ok((self, downloaded_file))
}

fn install<'t>(
async fn install<'t>(
&self,
installer_file: File,
tx: Transaction<'t>,
Expand All @@ -732,12 +734,14 @@ impl<'a> ComponentBinary<'a> {
return Err(RustupError::CorruptComponent(short_name).into());
}

let tx = package.install(
&manifestation.installation,
&pkg_name,
Some(short_pkg_name),
tx,
);
let tx = package
.install(
&manifestation.installation,
&pkg_name,
Some(short_pkg_name),
tx,
)
.await;
self.status.installed();
tx
}
Expand Down
55 changes: 38 additions & 17 deletions tests/suite/dist_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ fn package_bad_version() {
assert!(DirectoryPackage::new(tempdir.path().to_owned(), true).is_err());
}

#[test]
fn basic_install() {
#[tokio::test]
async fn basic_install() {
let mock = MockInstallerBuilder {
components: vec![MockComponentBuilder {
name: "mycomponent".to_string(),
Expand All @@ -98,7 +98,10 @@ fn basic_install() {

let cx = DistContext::new(Some(mock)).unwrap();
let (tx, components, pkg) = cx.start().unwrap();
let tx = pkg.install(&components, "mycomponent", None, tx).unwrap();
let tx = pkg
.install(&components, "mycomponent", None, tx)
.await
.unwrap();
tx.commit();

assert!(utils::path_exists(cx.inst_dir.path().join("bin/foo")));
Expand All @@ -113,8 +116,8 @@ fn basic_install() {
assert!(components.find("mycomponent").unwrap().is_some());
}

#[test]
fn multiple_component_install() {
#[tokio::test]
async fn multiple_component_install() {
let mock = MockInstallerBuilder {
components: vec![
MockComponentBuilder {
Expand All @@ -130,8 +133,14 @@ fn multiple_component_install() {

let cx = DistContext::new(Some(mock)).unwrap();
let (tx, components, pkg) = cx.start().unwrap();
let tx = pkg.install(&components, "mycomponent", None, tx).unwrap();
let tx = pkg.install(&components, "mycomponent2", None, tx).unwrap();
let tx = pkg
.install(&components, "mycomponent", None, tx)
.await
.unwrap();
let tx = pkg
.install(&components, "mycomponent2", None, tx)
.await
.unwrap();
tx.commit();

assert!(utils::path_exists(cx.inst_dir.path().join("bin/foo")));
Expand All @@ -141,8 +150,8 @@ fn multiple_component_install() {
assert!(components.find("mycomponent2").unwrap().is_some());
}

#[test]
fn uninstall() {
#[tokio::test]
async fn uninstall() {
let mock = MockInstallerBuilder {
components: vec![
MockComponentBuilder {
Expand All @@ -162,8 +171,14 @@ fn uninstall() {

let cx = DistContext::new(Some(mock)).unwrap();
let (tx, components, pkg) = cx.start().unwrap();
let tx = pkg.install(&components, "mycomponent", None, tx).unwrap();
let tx = pkg.install(&components, "mycomponent2", None, tx).unwrap();
let tx = pkg
.install(&components, "mycomponent", None, tx)
.await
.unwrap();
let tx = pkg
.install(&components, "mycomponent2", None, tx)
.await
.unwrap();
tx.commit();

// Now uninstall
Expand Down Expand Up @@ -193,8 +208,8 @@ fn uninstall_best_effort() {
//unimplemented!()
}

#[test]
fn component_bad_version() {
#[tokio::test]
async fn component_bad_version() {
let mock = MockInstallerBuilder {
components: vec![MockComponentBuilder {
name: "mycomponent".to_string(),
Expand All @@ -204,7 +219,10 @@ fn component_bad_version() {

let cx = DistContext::new(Some(mock)).unwrap();
let (tx, components, pkg) = cx.start().unwrap();
let tx = pkg.install(&components, "mycomponent", None, tx).unwrap();
let tx = pkg
.install(&components, "mycomponent", None, tx)
.await
.unwrap();
tx.commit();

// Write a bogus version to the component manifest directory
Expand All @@ -224,8 +242,8 @@ fn component_bad_version() {
}

// Installing to a prefix that doesn't exist creates it automatically
#[test]
fn install_to_prefix_that_does_not_exist() {
#[tokio::test]
async fn install_to_prefix_that_does_not_exist() {
let mock = MockInstallerBuilder {
components: vec![MockComponentBuilder {
name: "mycomponent".to_string(),
Expand All @@ -237,7 +255,10 @@ fn install_to_prefix_that_does_not_exist() {
let does_not_exist = cx.inst_dir.path().join("does_not_exist");
cx.prefix = InstallPrefix::from(does_not_exist.clone());
let (tx, components, pkg) = cx.start().unwrap();
let tx = pkg.install(&components, "mycomponent", None, tx).unwrap();
let tx = pkg
.install(&components, "mycomponent", None, tx)
.await
.unwrap();
tx.commit();

// The directory that does not exist
Expand Down
Loading