Skip to content

Commit ed6f719

Browse files
authored
Merge pull request #2236 from rbtcollins/2229
Fix #2229 detect available memory
2 parents cc773b2 + 7fb9d3f commit ed6f719

File tree

10 files changed

+153
-57
lines changed

10 files changed

+153
-57
lines changed

Cargo.lock

Lines changed: 64 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ chrono = "0.4"
2525
clap = "2"
2626
download = { path = "download" }
2727
error-chain = "0.12"
28+
effective-limits = "0.3"
2829
flate2 = "1"
2930
git-testament = "0.1.4"
3031
home = "0.5"

src/cli/common.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::self_update;
55
use crate::term2;
66
use git_testament::{git_testament, render_testament};
77
use lazy_static::lazy_static;
8+
use rustup::dist::notifications as dist_notifications;
9+
use rustup::utils::notifications as util_notifications;
810
use rustup::utils::notify::NotificationLevel;
911
use rustup::utils::utils;
1012
use rustup::{Cfg, Notification, Toolchain, UpdateStatus};
@@ -104,21 +106,29 @@ pub fn read_line() -> Result<String> {
104106
.ok_or_else(|| "unable to read from stdin for confirmation".into())
105107
}
106108

107-
pub fn set_globals(verbose: bool, quiet: bool) -> Result<Cfg> {
108-
use crate::download_tracker::DownloadTracker;
109-
use std::cell::RefCell;
110-
111-
let download_tracker = RefCell::new(DownloadTracker::new().with_display_progress(!quiet));
109+
#[derive(Default)]
110+
struct NotifyOnConsole {
111+
ram_notice_shown: bool,
112+
verbose: bool,
113+
}
112114

113-
Ok(Cfg::from_env(Arc::new(move |n: Notification<'_>| {
114-
if download_tracker.borrow_mut().handle_notification(&n) {
115-
return;
116-
}
115+
impl NotifyOnConsole {
116+
fn handle(&mut self, n: Notification<'_>) {
117+
if let Notification::Install(dist_notifications::Notification::Utils(
118+
util_notifications::Notification::SetDefaultBufferSize(_),
119+
)) = &n
120+
{
121+
if self.ram_notice_shown {
122+
return;
123+
} else {
124+
self.ram_notice_shown = true;
125+
}
126+
};
117127
let level = n.level();
118128
for n in format!("{}", n).lines() {
119129
match level {
120130
NotificationLevel::Verbose => {
121-
if verbose {
131+
if self.verbose {
122132
verbose!("{}", n);
123133
}
124134
}
@@ -133,6 +143,24 @@ pub fn set_globals(verbose: bool, quiet: bool) -> Result<Cfg> {
133143
}
134144
}
135145
}
146+
}
147+
}
148+
149+
pub fn set_globals(verbose: bool, quiet: bool) -> Result<Cfg> {
150+
use crate::download_tracker::DownloadTracker;
151+
use std::cell::RefCell;
152+
153+
let download_tracker = RefCell::new(DownloadTracker::new().with_display_progress(!quiet));
154+
let console_notifier = RefCell::new(NotifyOnConsole {
155+
verbose,
156+
..Default::default()
157+
});
158+
159+
Ok(Cfg::from_env(Arc::new(move |n: Notification<'_>| {
160+
if download_tracker.borrow_mut().handle_notification(&n) {
161+
return;
162+
}
163+
console_notifier.borrow_mut().handle(n);
136164
}))?)
137165
}
138166

src/dist/component/package.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,17 +165,30 @@ struct MemoryBudget {
165165

166166
// Probably this should live in diskio but ¯\_(ツ)_/¯
167167
impl MemoryBudget {
168-
fn new(max_file_size: usize) -> Self {
169-
const DEFAULT_UNPACK_RAM: usize = 400 * 1024 * 1024;
170-
let unpack_ram = if let Ok(budget_str) = env::var("RUSTUP_UNPACK_RAM") {
171-
if let Ok(budget) = budget_str.parse::<usize>() {
172-
budget
173-
} else {
174-
DEFAULT_UNPACK_RAM
168+
fn new(
169+
max_file_size: usize,
170+
effective_max_ram: usize,
171+
notify_handler: Option<&dyn Fn(Notification<'_>)>,
172+
) -> Self {
173+
const DEFAULT_UNPACK_RAM_MAX: usize = 500 * 1024 * 1024;
174+
const RAM_ALLOWANCE_FOR_RUSTUP_AND_BUFFERS: usize = 100 * 1024 * 1024;
175+
let ram_for_unpacking = effective_max_ram - RAM_ALLOWANCE_FOR_RUSTUP_AND_BUFFERS;
176+
let default_max_unpack_ram = std::cmp::min(DEFAULT_UNPACK_RAM_MAX, ram_for_unpacking);
177+
let unpack_ram = match env::var("RUSTUP_UNPACK_RAM")
178+
.ok()
179+
.and_then(|budget_str| budget_str.parse::<usize>().ok())
180+
{
181+
// Note: In future we may want to add a warning or even an override if a user
182+
// supplied budget is larger than effective_max_ram.
183+
Some(budget) => budget,
184+
None => {
185+
if let Some(h) = notify_handler {
186+
h(Notification::SetDefaultBufferSize(default_max_unpack_ram))
187+
}
188+
default_max_unpack_ram
175189
}
176-
} else {
177-
DEFAULT_UNPACK_RAM
178190
};
191+
179192
if max_file_size > unpack_ram {
180193
panic!("RUSTUP_UNPACK_RAM must be larger than {}", max_file_size);
181194
}
@@ -278,7 +291,12 @@ fn unpack_without_first_dir<'a, R: Read>(
278291
.entries()
279292
.chain_err(|| ErrorKind::ExtractingPackage)?;
280293
const MAX_FILE_SIZE: u64 = 200_000_000;
281-
let mut budget = MemoryBudget::new(MAX_FILE_SIZE as usize);
294+
let effective_max_ram = effective_limits::memory_limit()?;
295+
let mut budget = MemoryBudget::new(
296+
MAX_FILE_SIZE as usize,
297+
effective_max_ram as usize,
298+
notify_handler,
299+
);
282300

283301
let mut directories: HashMap<PathBuf, DirStatus> = HashMap::new();
284302
// Path is presumed to exist. Call it a precondition.

src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub const TOOLSTATE_MSG: &str =
2222
error_chain! {
2323
links {
2424
Download(download::Error, download::ErrorKind);
25+
Limits(effective_limits::Error, effective_limits::ErrorKind);
2526
}
2627

2728
foreign_links {

src/utils/notifications.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::path::Path;
44
use url::Url;
55

66
use crate::utils::notify::NotificationLevel;
7-
use crate::utils::units::Unit;
7+
use crate::utils::units::{self, Unit};
88

99
#[derive(Debug)]
1010
pub enum Notification<'a> {
@@ -27,6 +27,10 @@ pub enum Notification<'a> {
2727
DownloadPopUnit,
2828
NoCanonicalPath(&'a Path),
2929
ResumingPartialDownload,
30+
/// This would make more sense as a crate::notifications::Notification
31+
/// member, but the notification callback is already narrowed to
32+
/// utils::notifications by the time tar unpacking is called.
33+
SetDefaultBufferSize(usize),
3034
UsingCurl,
3135
UsingReqwest,
3236
/// Renaming encountered a file in use error and is retrying.
@@ -54,7 +58,7 @@ impl<'a> Notification<'a> {
5458
| ResumingPartialDownload
5559
| UsingCurl
5660
| UsingReqwest => NotificationLevel::Verbose,
57-
RenameInUse(_, _) => NotificationLevel::Info,
61+
RenameInUse(_, _) | SetDefaultBufferSize(_) => NotificationLevel::Info,
5862
NoCanonicalPath(_) => NotificationLevel::Warn,
5963
}
6064
}
@@ -78,6 +82,11 @@ impl<'a> Display for Notification<'a> {
7882
src.display(),
7983
dest.display()
8084
),
85+
SetDefaultBufferSize(size) => write!(
86+
f,
87+
"Defaulting to {} unpack ram",
88+
units::Size::new(*size, units::Unit::B, units::UnitMode::Norm)
89+
),
8190
DownloadingFile(url, _) => write!(f, "downloading file from: '{}'", url),
8291
DownloadContentLengthReceived(len) => write!(f, "download size is: '{}'", len),
8392
DownloadDataReceived(data) => write!(f, "received some data of size {}", data.len()),

tests/cli-exact.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ info: downloading component 'rust-docs'
3838
info: downloading component 'rust-std'
3939
info: downloading component 'rustc'
4040
info: installing component 'cargo'
41+
info: Defaulting to 500.0 MiB unpack ram
4142
info: installing component 'rust-docs'
4243
info: installing component 'rust-std'
4344
info: installing component 'rustc'
@@ -172,6 +173,7 @@ info: downloading component 'rust-docs'
172173
info: downloading component 'rust-std'
173174
info: downloading component 'rustc'
174175
info: installing component 'cargo'
176+
info: Defaulting to 500.0 MiB unpack ram
175177
info: installing component 'rust-docs'
176178
info: installing component 'rust-std'
177179
info: installing component 'rustc'
@@ -504,6 +506,7 @@ fn cross_install_indicates_target() {
504506
&format!(
505507
r"info: downloading component 'rust-std' for '{0}'
506508
info: installing component 'rust-std' for '{0}'
509+
info: Defaulting to 500.0 MiB unpack ram
507510
",
508511
clitools::CROSS_ARCH1
509512
),

tests/cli-rustup.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ info: removing previous version of component 'rust-docs'
5656
info: removing previous version of component 'rust-std'
5757
info: removing previous version of component 'rustc'
5858
info: installing component 'cargo'
59+
info: Defaulting to 500.0 MiB unpack ram
5960
info: installing component 'rust-docs'
6061
info: installing component 'rust-std'
6162
info: installing component 'rustc'
@@ -96,6 +97,7 @@ info: removing previous version of component 'rust-docs'
9697
info: removing previous version of component 'rust-std'
9798
info: removing previous version of component 'rustc'
9899
info: installing component 'cargo'
100+
info: Defaulting to 500.0 MiB unpack ram
99101
info: installing component 'rust-docs'
100102
info: installing component 'rust-std'
101103
info: installing component 'rustc'
@@ -160,6 +162,7 @@ info: removing previous version of component 'rust-docs'
160162
info: removing previous version of component 'rust-std'
161163
info: removing previous version of component 'rustc'
162164
info: installing component 'cargo'
165+
info: Defaulting to 500.0 MiB unpack ram
163166
info: installing component 'rust-docs'
164167
info: installing component 'rust-std'
165168
info: installing component 'rustc'
@@ -230,6 +233,7 @@ info: removing previous version of component 'rust-docs'
230233
info: removing previous version of component 'rust-std'
231234
info: removing previous version of component 'rustc'
232235
info: installing component 'cargo'
236+
info: Defaulting to 500.0 MiB unpack ram
233237
info: installing component 'rust-docs'
234238
info: installing component 'rust-std'
235239
info: installing component 'rustc'
@@ -291,6 +295,7 @@ info: downloading component 'rust-docs'
291295
info: downloading component 'rust-std'
292296
info: downloading component 'rustc'
293297
info: installing component 'cargo'
298+
info: Defaulting to 500.0 MiB unpack ram
294299
info: installing component 'rust-docs'
295300
info: installing component 'rust-std'
296301
info: installing component 'rustc'

tests/cli-self-upd.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ info: downloading component 'rust-docs'
883883
info: downloading component 'rust-std'
884884
info: downloading component 'rustc'
885885
info: installing component 'cargo'
886+
info: Defaulting to 500.0 MiB unpack ram
886887
info: installing component 'rust-docs'
887888
info: installing component 'rust-std'
888889
info: installing component 'rustc'

tests/cli-v2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,7 @@ info: downloading component 'cargo'
13421342
info: downloading component 'rust-docs'
13431343
info: downloading component 'rustc'
13441344
info: installing component 'cargo'
1345+
info: Defaulting to 500.0 MiB unpack ram
13451346
info: installing component 'rust-docs'
13461347
info: installing component 'rustc'
13471348
"

0 commit comments

Comments
 (0)