Skip to content

Commit 73bbb09

Browse files
committed
moss: Add percentage callback for global download progress
By using an atomic total bytes to download, we can get a nice smooth progress bar of all packages as they download despite being async. This doesn't account for unpacking or db storing yet. We may also wish to spit the individual progress reporting in the future as well.
1 parent d0b5f13 commit 73bbb09

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

moss/src/cli/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub fn handle(args: &ArgMatches, installation: Installation, debug: bool) -> Res
118118
return Err(Error::Cancelled);
119119
}
120120

121-
runtime::block_on(client.cache_packages(&synced))?;
121+
runtime::block_on(client.cache_packages(&synced, None))?;
122122

123123
// Map finalized state to a [`Selection`] by referencing
124124
// it's value from the previous state

moss/src/client/install.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub fn install(client: &mut Client, pkgs: &[&str], yes: bool) -> Result<Timing,
9696
instant = Instant::now();
9797

9898
// Cache packages
99-
runtime::block_on(client.cache_packages(&missing))?;
99+
runtime::block_on(client.cache_packages(&missing, None))?;
100100

101101
timing.fetch = instant.elapsed();
102102
instant = Instant::now();

moss/src/client/mod.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ use std::{
1414
fmt, io,
1515
os::{fd::RawFd, unix::fs::symlink},
1616
path::{Path, PathBuf},
17-
sync::Arc,
17+
sync::{
18+
Arc,
19+
atomic::{AtomicU64, Ordering},
20+
},
1821
time::{Duration, Instant},
1922
};
2023

@@ -86,6 +89,11 @@ pub enum ProgressStage {
8689
System = 2,
8790
}
8891

92+
#[derive(Clone, Copy, Debug)]
93+
pub enum DownloadCallback {
94+
DownloadOverall(f32),
95+
}
96+
8997
impl Client {
9098
/// Construct a new Client for the given [`Installation`]
9199
pub fn new(client_name: impl ToString, installation: Installation) -> Result<Client, Error> {
@@ -490,7 +498,11 @@ impl Client {
490498
}
491499

492500
/// Download & unpack the provided packages. Packages already cached will be validated & skipped.
493-
pub async fn cache_packages<T>(&self, packages: &[T]) -> Result<(), Error>
501+
pub async fn cache_packages<T>(
502+
&self,
503+
packages: &[T],
504+
progress_callback: Option<Arc<dyn Fn(DownloadCallback) + Send + Sync>>,
505+
) -> Result<(), Error>
494506
where
495507
T: Borrow<Package>,
496508
{
@@ -509,6 +521,12 @@ impl Client {
509521

510522
let unpacking_in_progress = cache::UnpackingInProgress::default();
511523

524+
let total_bytes = packages.iter().fold(0, |acc, p| {
525+
let pkg: &Package = p.borrow();
526+
acc + pkg.meta.download_size.unwrap_or_default()
527+
});
528+
let total_completed_bytes = &AtomicU64::new(0);
529+
512530
// Download and unpack each package
513531
let cached = stream::iter(packages)
514532
.map(|package| async {
@@ -536,12 +554,24 @@ impl Client {
536554
// Download and update progress
537555
let download = cache::fetch(&package.meta, &self.installation, |progress| {
538556
progress_bar.inc(progress.delta);
557+
if let Some(ref callback) = progress_callback {
558+
callback({
559+
DownloadCallback::DownloadOverall({
560+
let current_pkg_completed = progress.completed;
561+
let total_completed =
562+
total_completed_bytes.load(Ordering::Relaxed) + current_pkg_completed;
563+
total_completed as f32 / total_bytes as f32
564+
})
565+
})
566+
}
539567
})
540568
.await?;
541569
let is_cached = download.was_cached;
542570

543571
// Move rest of blocking code to threadpool
544572

573+
total_completed_bytes.fetch_add(package.meta.download_size.unwrap_or_default(), Ordering::Relaxed);
574+
545575
let multi_progress = multi_progress.clone();
546576
let total_progress = total_progress.clone();
547577
let unpacking_in_progress = unpacking_in_progress.clone();

moss/src/client/verify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ pub fn verify(client: &Client, yes: bool, verbose: bool) -> Result<(), client::E
214214
println!("Reinstalling packages");
215215

216216
// And re-cache all packages that comprise the corrupt / missing asset
217-
runtime::block_on(client.cache_packages(&issue_packages))?;
217+
runtime::block_on(client.cache_packages(&issue_packages, None))?;
218218
}
219219

220220
// Now we must fix any states that referenced these packages

0 commit comments

Comments
 (0)