Skip to content

Conversation

FranciscoTGouveia
Copy link
Contributor

Continuation of #4436.

This change aims to speed up the overall performance of the rustup [toolchain] install command by allowing the installation of a component to start immediately after its download completes.
This approach is particularly beneficial for slower connections, as it enables installations to progress in parallel with ongoing downloads -- so by the time all downloads are finished, all installations should be completed as well.

NB: This PR is not yet ready for review. I believe this change should be backed by benchmarks and user feedback before moving forward. I’ll share those here in the next couple of days.

Even though downloads are done concurrently, the installations are done
sequentially. This means that, as downloads complete, they are in a
queue (an mpsc channel) waiting to be consumed by the future responsible
for the (sequential) installations.
if counter >= total_components {
break;
}
if let Some(message) = download_rx.recv().await {
Copy link
Member

Choose a reason for hiding this comment

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

Could it be that the counter never gets incremented because .recv().await returns None?

Did you mean something like this instead?

while counter < total_components && let Some(_) = ... {  ...; counter += 1; }

Ok(new_tx) => {
current_tx = new_tx;
}
Err(e) => {
Copy link
Member

Choose a reason for hiding this comment

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

If I'm not mistaken, Err(e) => return Err(e) is just ? 🤔

@@ -35,7 +35,6 @@ async fn rustup_stable() {
.with_stderr(snapbox::str![[r#"
info: syncing channel updates for 'stable-[HOST_TRIPLE]'
info: latest update on 2015-01-02, rust version 1.1.0 (hash-stable-1.1.0)
info: downloading component[..]
Copy link
Member

Choose a reason for hiding this comment

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

Possibly squash this commit with the one that has broken these tests.

@@ -122,6 +124,13 @@ impl Display for Notification<'_> {
write!(f, "installing component '{}' for '{}'", c, t.unwrap())
}
}
ComponentInstalled(c, h, t) => {
if Some(h) == t.as_ref() || t.is_none() {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Now that we are at it, I would probably give an extra commit to avoid the t.unwrap() here by flipping the if and writing something like:

if let Some(t) = t && t != h { ... } else { ... }

ProgressStyle::with_template( if pb.position() != 0 {
"{msg:>12.bold} downloaded {total_bytes} in {elapsed} installing now {spinner:.green}"
} else {
"{msg:>12.bold} component already downloaded, installing now {spinner:.green}"
Copy link
Member

Choose a reason for hiding this comment

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

Nit: the , installing now, installing now and and installed might seem inconsistent. How about just and installed and and installing? I believe the spinner can compensate for the minor difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants