Skip to content

Commit 72803ba

Browse files
committed
Implement progress like it was before
Except that now it should go towards zero on disconnect.
1 parent 9b9a0fc commit 72803ba

File tree

2 files changed

+65
-9
lines changed

2 files changed

+65
-9
lines changed

src/cargo/sources/git/oxide.rs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! This module contains all code sporting `gitoxide` for operations on `git` repositories and it mirrors
22
//! `utils` closely for now. One day it can be renamed into `utils` once `git2` isn't required anymore.
33
4-
use crate::util::{network, Progress};
4+
use crate::util::{human_readable_bytes, network, MetricsCounter, Progress};
55
use crate::{CargoResult, Config};
66
use git_repository as git;
7-
use std::sync::atomic::AtomicBool;
7+
use std::sync::atomic::{AtomicBool, Ordering};
88
use std::sync::Arc;
9-
use std::time::Duration;
9+
use std::time::{Duration, Instant};
1010

1111
/// For the time being, `repo_path` makes it easy to instantiate a gitoxide repo just for fetching.
1212
/// In future this may change to be the gitoxide repository itself.
@@ -49,22 +49,78 @@ pub fn with_retry_and_progress(
4949
.ok()
5050
.unwrap_or_default()
5151
.auto_deregister();
52-
let should_interrupt = AtomicBool::new(false);
5352
let mut progress_bar = Progress::new("Fetch", config);
5453
std::thread::scope(move |s| {
5554
s.spawn({
5655
let root = Arc::downgrade(&progress_root);
5756
move || -> CargoResult<()> {
57+
const READ_PACK_BYTES: [u8; 4] = *b"BWRB";
58+
const DELTA_INDEX_OBJECTS: [u8; 4] = *b"IWIO";
59+
const RESOLVE_OBJECTS: [u8; 4] = *b"IWRO";
60+
61+
// We choose `N=10` here to make a `300ms * 10slots ~= 3000ms`
62+
// sliding window for tracking the data transfer rate (in bytes/s).
63+
let mut last_update = Instant::now();
64+
let mut counter = MetricsCounter::<10>::new(0, last_update);
65+
5866
let mut tasks = Vec::with_capacity(10);
5967
while let Some(root) = root.upgrade() {
6068
root.sorted_snapshot(&mut tasks);
61-
progress_bar.tick(0, 10, "TBD")?;
62-
// dbg!(&tasks);
69+
let counters = tasks
70+
.iter()
71+
.find_map(|(_, t)| {
72+
(t.id == READ_PACK_BYTES).then(|| t.progress.as_ref().expect("set"))
73+
})
74+
.and_then(|read| {
75+
tasks.iter().find_map(|(_, t)| {
76+
(t.id == DELTA_INDEX_OBJECTS)
77+
.then(|| (t.progress.as_ref().expect("set"), Some(read)))
78+
})
79+
})
80+
.or_else(|| {
81+
tasks.iter().find_map(|(_, t)| {
82+
(t.id == RESOLVE_OBJECTS)
83+
.then(|| (t.progress.as_ref().expect("set"), None))
84+
})
85+
});
86+
let progress_info = match counters {
87+
Some((objs, None)) => {
88+
// Resolving deltas.
89+
let objects = objs.step.load(Ordering::Relaxed);
90+
let total_objects = objs.done_at.expect("known amount of objects");
91+
Some((
92+
objects,
93+
total_objects,
94+
format!(", ({}/{}) resolving deltas", objects, total_objects),
95+
))
96+
}
97+
Some((objs, Some(read_pack))) => {
98+
// Receiving objects.
99+
let objects = objs.step.load(Ordering::Relaxed);
100+
let total_objects = objs.done_at.expect("known amount of objects");
101+
let received_bytes = read_pack.step.load(Ordering::Relaxed);
102+
103+
let now = Instant::now();
104+
counter.add(received_bytes, now);
105+
last_update = now;
106+
let (rate, unit) = human_readable_bytes(counter.rate() as u64);
107+
Some((objects, total_objects, format!(", {:.2}{}/s", rate, unit)))
108+
}
109+
None => {
110+
counter = MetricsCounter::<10>::new(0, last_update);
111+
None
112+
}
113+
};
114+
if let Some((objects, total_objects, msg)) = progress_info {
115+
progress_bar.tick(objects, total_objects, &msg)?;
116+
}
63117
std::thread::sleep(Duration::from_millis(300));
64118
}
65119
Ok(())
66120
}
67121
});
68-
network::with_retry(config, || cb(&repo, &should_interrupt, &mut progress))
122+
network::with_retry(config, || {
123+
cb(&repo, &git::interrupt::IS_INTERRUPTED, &mut progress)
124+
})
69125
})
70126
}

src/cargo/sources/git/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ pub fn fetch(
867867
oxide::with_retry_and_progress(
868868
&git2_repo.path().to_owned(),
869869
config,
870-
&mut |repo, should_interrupt, progress| {
870+
&mut |repo, should_interrupt, mut progress| {
871871
// The `fetch` operation here may fail spuriously due to a corrupt
872872
// repository. It could also fail, however, for a whole slew of other
873873
// reasons (aka network related reasons). We want Cargo to automatically
@@ -889,7 +889,7 @@ pub fn fetch(
889889
refspecs.iter().map(|s| s.as_str()),
890890
git::remote::Direction::Fetch,
891891
)?
892-
.connect(git::remote::Direction::Fetch, progress.add_child("fetch"))?
892+
.connect(git::remote::Direction::Fetch, &mut progress)?
893893
.prepare_fetch(git::remote::ref_map::Options::default())?
894894
.receive(should_interrupt);
895895
let err = match res {

0 commit comments

Comments
 (0)