From 51f7329ddbdee8d1ed32ac2e7a1e43a3752d49b7 Mon Sep 17 00:00:00 2001 From: reidliu41 Date: Sat, 14 Nov 2026 06:53:45 -0800 Subject: [PATCH 1/2] refactor(dist): move CONFIG_FILE to module bottom --- src/dist/manifestation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index d19048f0f3..bfac6f2b93 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -36,8 +36,6 @@ use crate::{ utils, }; -pub(crate) const CONFIG_FILE: &str = "multirust-config.toml"; - #[derive(Debug)] pub struct Manifestation { installation: Components, @@ -839,5 +837,7 @@ impl ComponentInstall { } } +pub(crate) const CONFIG_FILE: &str = "multirust-config.toml"; + #[cfg(feature = "test")] pub const CHECKPOINT_UPDATE_BEFORE_METADATA: &str = "update-before-metadata"; From a0586b0faf14ad7dcdb8b103ef066d1c6b7a6b86 Mon Sep 17 00:00:00 2001 From: reidliu41 Date: Sat, 14 Nov 2026 06:58:57 -0800 Subject: [PATCH 2/2] perf(config): avoid full manifest parsing for release hints --- src/config.rs | 4 +-- src/dist/manifest.rs | 4 +++ src/dist/manifestation.rs | 47 +++++++++++++++++++++++++++++++++ src/dist/manifestation/tests.rs | 12 +++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 7a9c4197b0..7f94f2c477 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1122,8 +1122,8 @@ impl<'a> Cfg<'a> { Err(e) => return Err(anyhow!(e).context("while looking for local stable toolchain")), }; let release_date_str = match stable.get_manifestation() { - Ok(manifestation) => match manifestation.load_manifest() { - Ok(Some(manifest)) => manifest.date, + Ok(manifestation) => match manifestation.load_manifest_date() { + Ok(Some(date)) => date, Ok(None) | Err(_) => FALLBACK_RELEASE_DATE.to_owned(), }, Err(_) => FALLBACK_RELEASE_DATE.to_owned(), diff --git a/src/dist/manifest.rs b/src/dist/manifest.rs index ad22abb03b..768e3f6ec6 100644 --- a/src/dist/manifest.rs +++ b/src/dist/manifest.rs @@ -332,6 +332,10 @@ impl Manifest { Ok(manifest) } + pub(crate) fn parse_date(header: &str) -> anyhow::Result { + Ok(toml::from_str::(header)?.date) + } + pub fn stringify(self) -> anyhow::Result { Ok(toml::to_string(&self)?) } diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index bfac6f2b93..376178b0d5 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -6,6 +6,8 @@ mod tests; use std::{ collections::VecDeque, + fs, + io::{BufRead, BufReader, Read}, path::Path, pin::Pin, sync::Arc, @@ -376,6 +378,26 @@ impl Manifestation { } } + #[tracing::instrument(level = "trace")] + pub(crate) fn load_manifest_date(&self) -> anyhow::Result> { + let prefix = self.installation.prefix(); + if let Some(manifest_path) = prefix.dist_manifest() { + let date = fs::File::open(&manifest_path) + .map_err(anyhow::Error::from) + .and_then(read_manifest_date); + match date { + Ok(date) => return Ok(Some(date)), + Err(error) => debug!( + path = %manifest_path.display(), + %error, + "failed to read manifest date from header; falling back to full manifest parsing" + ), + } + } + + Ok(self.load_manifest()?.map(|manifest| manifest.date)) + } + /// Installation using the legacy v1 manifest format pub(crate) async fn update_v1( &self, @@ -469,6 +491,26 @@ impl Manifestation { } } +/// Parses the manifest date from the root-level fields before the first line +/// whose first non-whitespace character is `[`, reading at most +/// `MANIFEST_HEADER_SIZE_LIMIT` bytes. +fn read_manifest_date(reader: impl Read) -> anyhow::Result { + let mut reader = BufReader::new(reader.take(MANIFEST_HEADER_SIZE_LIMIT)); + let mut header = String::new(); + loop { + let line_start = header.len(); + if reader.read_line(&mut header)? == 0 { + break; + } + if header[line_start..].trim_start().starts_with('[') { + header.truncate(line_start); + break; + } + } + + Manifest::parse_date(&header) +} + struct InstallEvents<'a, F> { manifestation: Arc, components: vec::IntoIter>, @@ -839,5 +881,10 @@ impl ComponentInstall { pub(crate) const CONFIG_FILE: &str = "multirust-config.toml"; +// The serialized manifest currently places `date` within the first 64 bytes. +// Leave some headroom for reordered or additional root keys; if the header +// exceeds this limit, loading falls back to parsing the full manifest. +const MANIFEST_HEADER_SIZE_LIMIT: u64 = 128; + #[cfg(feature = "test")] pub const CHECKPOINT_UPDATE_BEFORE_METADATA: &str = "update-before-metadata"; diff --git a/src/dist/manifestation/tests.rs b/src/dist/manifestation/tests.rs index 8649100d94..84da1e8ea0 100644 --- a/src/dist/manifestation/tests.rs +++ b/src/dist/manifestation/tests.rs @@ -14,6 +14,7 @@ use std::{ use anyhow::anyhow; use url::Url; +use super::read_manifest_date; use crate::{ config::Cfg, dist::{ @@ -38,6 +39,17 @@ use crate::{ const SHA256_HASH_LEN: usize = 64; +#[test] +fn read_manifest_date_from_serialized_manifest() -> anyhow::Result<()> { + let serialized = Manifest::parse(include_str!( + "../manifest/tests/channel-rust-nightly-example.toml" + ))? + .stringify()?; + + assert_eq!(read_manifest_date(serialized.as_bytes())?, "2015-10-10"); + Ok(()) +} + // Creates a mock dist server populated with some test data fn create_mock_dist_server( path: &Path,