Skip to content

Commit 789efe3

Browse files
committed
Cool down progress loop.
Previously it actually was very hot and needed an entire CPU for itself due to constant querying of progress information. Now it's slowed down by consistently sleeping for a short amount of time. This time should be short enough to not let the progress bar hold up the overall progress of the fetch operation, hence the 10ms sleep time, reducing the worst-case hold-up to 10ms.
1 parent 6e96095 commit 789efe3

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/cargo/sources/git/oxide.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,34 @@ fn translate_progress_to_bar(
6969

7070
// We choose `N=10` here to make a `300ms * 10slots ~= 3000ms`
7171
// sliding window for tracking the data transfer rate (in bytes/s).
72-
let mut last_update = Instant::now();
73-
let mut counter = MetricsCounter::<10>::new(0, last_update);
72+
let mut last_percentage_update = Instant::now();
73+
let mut last_fast_update = Instant::now();
74+
let mut counter = MetricsCounter::<10>::new(0, last_percentage_update);
7475

7576
let mut tasks = Vec::with_capacity(10);
76-
let update_interval = std::time::Duration::from_millis(300);
77-
let short_check_interval = Duration::from_millis(50);
77+
let slow_check_interval = std::time::Duration::from_millis(300);
78+
let fast_check_interval = Duration::from_millis(50);
79+
let sleep_interval = Duration::from_millis(10);
80+
debug_assert_eq!(
81+
slow_check_interval.as_millis() % fast_check_interval.as_millis(),
82+
0,
83+
"progress should be smoother by keeping these as multiples of each other"
84+
);
85+
debug_assert_eq!(
86+
fast_check_interval.as_millis() % sleep_interval.as_millis(),
87+
0,
88+
"progress should be smoother by keeping these as multiples of each other"
89+
);
7890

7991
while let Some(root) = root.upgrade() {
80-
let not_yet = last_update.elapsed() < update_interval;
81-
if not_yet {
82-
std::thread::sleep(short_check_interval);
92+
std::thread::sleep(sleep_interval);
93+
let needs_update = last_fast_update.elapsed() >= fast_check_interval;
94+
if !needs_update {
95+
continue;
8396
}
97+
let now = Instant::now();
98+
last_fast_update = now;
99+
84100
root.sorted_snapshot(&mut tasks);
85101

86102
fn progress_by_id(
@@ -115,10 +131,10 @@ fn translate_progress_to_bar(
115131
let total_objects = objs.done_at.expect("known amount of objects");
116132
let received_bytes = read_pack.step.load(Ordering::Relaxed);
117133

118-
let now = Instant::now();
119-
if !not_yet {
134+
let needs_percentage_update = last_percentage_update.elapsed() >= slow_check_interval;
135+
if needs_percentage_update {
120136
counter.add(received_bytes, now);
121-
last_update = now;
137+
last_percentage_update = now;
122138
}
123139
let (rate, unit) = human_readable_bytes(counter.rate() as u64);
124140
let msg = format!(", {rate:.2}{unit}/s");

0 commit comments

Comments
 (0)