-
Notifications
You must be signed in to change notification settings - Fork 1k
Run a parallel pre-check before updating toolchains #4752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b10a7dd
4a68765
3afbe36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -955,7 +955,11 @@ impl<'cfg, 'a> DistOptions<'cfg, 'a> { | |
| // | ||
| // Returns the manifest's hash if anything changed. | ||
| #[tracing::instrument(level = "trace", err(level = "trace"), skip_all, fields(profile = ?self.profile, prefix = %prefix.path().display()))] | ||
| pub(crate) async fn install_into(&self, prefix: &InstallPrefix) -> Result<Option<String>> { | ||
| pub(crate) async fn install_into( | ||
| &self, | ||
| prefix: &InstallPrefix, | ||
| manifest: Option<(ManifestV2, String)>, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fairly unclear with all the places you're passing around
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @djc It is worth noting that this is the return value of |
||
| ) -> Result<Option<String>> { | ||
| let fresh_install = !prefix.path().exists(); | ||
| // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file | ||
| if fresh_install && self.update_hash.exists() { | ||
|
|
@@ -1013,6 +1017,7 @@ impl<'cfg, 'a> DistOptions<'cfg, 'a> { | |
| }; | ||
|
|
||
| let mut toolchain = self.toolchain.clone(); | ||
| let mut prefetched_manifest = manifest; | ||
| let res = loop { | ||
| let result = try_update_from_dist_( | ||
| &self.dl_cfg, | ||
|
|
@@ -1028,6 +1033,7 @@ impl<'cfg, 'a> DistOptions<'cfg, 'a> { | |
| self.targets, | ||
| &mut fetched, | ||
| self.cfg, | ||
| prefetched_manifest.take(), | ||
rami3l marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) | ||
| .await; | ||
|
|
||
|
|
@@ -1126,27 +1132,32 @@ async fn try_update_from_dist_( | |
| targets: &[&str], | ||
| fetched: &mut String, | ||
| cfg: &Cfg<'_>, | ||
| prefetched_manifest: Option<(ManifestV2, String)>, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this actually need to take ownership ownership of the manifest, or could it make do with a reference? |
||
| ) -> Result<Option<String>> { | ||
| let toolchain_str = toolchain.to_string(); | ||
| let manifestation = Manifestation::open(prefix.clone(), toolchain.target.clone())?; | ||
|
|
||
| // TODO: Add a notification about which manifest version is going to be used | ||
| info!("syncing channel updates for {toolchain_str}"); | ||
| match download | ||
| .dl_v2_manifest( | ||
| // Even if manifest has not changed, we must continue to install requested components. | ||
| // So if components or targets is not empty, we skip passing `update_hash` so that | ||
| // we essentially degenerate to `rustup component add` / `rustup target add` | ||
| if components.is_empty() && targets.is_empty() { | ||
| Some(update_hash) | ||
| } else { | ||
| None | ||
| }, | ||
| toolchain, | ||
| cfg, | ||
| ) | ||
| .await | ||
| { | ||
| let manifest_result = if prefetched_manifest.is_some() { | ||
| Ok(prefetched_manifest) | ||
| } else { | ||
| download | ||
| .dl_v2_manifest( | ||
| // Even if manifest has not changed, we must continue to install requested components. | ||
| // So if components or targets is not empty, we skip passing `update_hash` so that | ||
| // we essentially degenerate to `rustup component add` / `rustup target add` | ||
| if components.is_empty() && targets.is_empty() { | ||
| Some(update_hash) | ||
| } else { | ||
| None | ||
| }, | ||
| toolchain, | ||
| cfg, | ||
| ) | ||
| .await | ||
| }; | ||
| match manifest_result { | ||
| Ok(Some((m, hash))) => { | ||
| match m.get_rust_version() { | ||
| Ok(version) => info!("latest update on {} for version {version}", m.date), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ use tracing::debug; | |
|
|
||
| use crate::{ | ||
| config::Cfg, | ||
| dist::{DistOptions, prefix::InstallPrefix}, | ||
| dist::{DistOptions, manifest::Manifest, prefix::InstallPrefix}, | ||
| errors::RustupError, | ||
| toolchain::{CustomToolchainName, LocalToolchainName, Toolchain}, | ||
| utils, | ||
|
|
@@ -38,6 +38,13 @@ impl InstallMethod<'_, '_> { | |
| // Install a toolchain | ||
| #[tracing::instrument(level = "trace", err(level = "trace"), skip_all)] | ||
| pub(crate) async fn install(self) -> Result<UpdateStatus> { | ||
| self.install_with_manifest(None).await | ||
| } | ||
|
|
||
| pub(crate) async fn install_with_manifest( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest just adding the argument to |
||
| self, | ||
| manifest: Option<(Manifest, String)>, | ||
| ) -> Result<UpdateStatus> { | ||
| // Initialize rayon for use by the remove_dir_all crate limiting the number of threads. | ||
| // This will error if rayon is already initialized but it's fine to ignore that. | ||
| let _ = rayon::ThreadPoolBuilder::new() | ||
|
|
@@ -54,7 +61,7 @@ impl InstallMethod<'_, '_> { | |
| } | ||
|
|
||
| debug!("toolchain directory: {}", self.dest_path().display()); | ||
| let updated = self.run(&self.dest_path()).await?; | ||
| let updated = self.run(&self.dest_path(), manifest).await?; | ||
|
|
||
| let status = match updated { | ||
| false => { | ||
|
|
@@ -82,7 +89,7 @@ impl InstallMethod<'_, '_> { | |
| } | ||
| } | ||
|
|
||
| async fn run(&self, path: &Path) -> Result<bool> { | ||
| async fn run(&self, path: &Path, manifest: Option<(Manifest, String)>) -> Result<bool> { | ||
| if path.exists() { | ||
| // Don't uninstall first for Dist method | ||
| match self { | ||
|
|
@@ -104,7 +111,7 @@ impl InstallMethod<'_, '_> { | |
| } | ||
| InstallMethod::Dist(opts) => { | ||
| let prefix = &InstallPrefix::from(path.to_owned()); | ||
| let maybe_new_hash = opts.install_into(prefix).await?; | ||
| let maybe_new_hash = opts.install_into(prefix, manifest).await?; | ||
|
|
||
| if let Some(hash) = maybe_new_hash { | ||
| utils::write_file("update hash", &opts.update_hash, &hash)?; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -445,15 +445,18 @@ impl<'a> DistributableToolchain<'a> { | |
| Ok(()) | ||
| } | ||
|
|
||
| pub async fn show_dist_version(&self) -> anyhow::Result<Option<String>> { | ||
| match DownloadCfg::new(self.toolchain.cfg) | ||
| pub async fn fetch_dist_manifest(&self) -> anyhow::Result<Option<(Manifest, String)>> { | ||
| DownloadCfg::new(self.toolchain.cfg) | ||
| .dl_v2_manifest( | ||
| Some(&self.toolchain.cfg.get_hash_file(&self.desc, false)?), | ||
| &self.desc, | ||
| self.toolchain.cfg, | ||
| ) | ||
| .await? | ||
| { | ||
| .await | ||
| } | ||
|
|
||
| pub async fn show_dist_version(&self) -> anyhow::Result<Option<String>> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this has a single caller, maybe this should be inlined into its caller instead? (If not, should do top-down order such that |
||
| match self.fetch_dist_manifest().await? { | ||
| Some((manifest, _)) => Ok(Some(manifest.get_rust_version()?.to_string())), | ||
| None => Ok(None), | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is sort of just silencing/ignoring errors? Is that what we did before?
Instead of the type annotation, I would use turbofishing and leaving any inner types implied, as in
collect::<Vec<_>>().