chiark / gitweb /
otter cli: Use new Nest progress during bundle uploading
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 15 May 2022 23:57:02 +0000 (00:57 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 16 May 2022 02:09:35 +0000 (03:09 +0100)
This lets us show progress of zipfile preparation.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
cli/forgame.rs
cli/usebundles.rs
support/termprogress.rs

index 3aaea0b654f78550bfa89fc497be65d9f7b8a359..7153417fe638857177534c1f54bc624a92477306 100644 (file)
@@ -89,8 +89,13 @@ mod reset_game {
     }
 
     if args.bundles_only || args.bundles.len() != 0 {
+      let n_bundles = args.bundles.len();
+      let progress = ma.progressbar()?;
+      let mut progress = termprogress::Nest::with_total
+        (n_bundles as f32, progress);
+
       let local = args.bundles.into_iter().map(|file| {
-        BundleForUpload::prepare(file)
+        BundleForUpload::prepare(file, &mut progress)
       }).collect::<Result<Vec<_>,_>>()?;
 
       let resp = chan.cmd(&MgmtCommand::ListBundles { game: ma.instance() })?;
@@ -142,11 +147,8 @@ mod reset_game {
           if bundles_only {
             clear_game(&ma, &mut chan)?;
           }
-          let progress = ma.progressbar()?;
-          let n_bundles = local.len();
-          let mut progress = termprogress::Nest::new(progress);
           for (i, bundle) in local.into_iter().enumerate() {
-            progress.start_phase((i as f32)/(n_bundles as f32),
+            progress.start_phase(PROGFRAC_UPLOAD,
                                  format!("{}/{}", i, n_bundles));
             bundle.upload(&ma, &mut chan, &mut progress)?;
           }
index 83b70367b9fef6b225c8f599bffb0c8bbb15fcc2..0f61bd766e5bc6c7c808fd23f23003759c9b7d6c 100644 (file)
@@ -6,6 +6,10 @@ use super::*;
 
 //---------- upload-bundle ----------
 
+pub const PROGFRAC_PREP:   f32 = 0.20;
+pub const PROGFRAC_HASH:   f32 = 0.10;
+pub const PROGFRAC_UPLOAD: f32 = 0.70;
+
 #[derive(Debug)]
 pub struct BundleForUpload {
   pub file: String,
@@ -17,7 +21,9 @@ pub struct BundleForUpload {
 
 impl BundleForUpload {
   #[throws(AE)]
-  pub fn prepare(file: String) -> Self {
+  pub fn prepare(file: String, progress: &mut termprogress::Nest) -> Self {
+    progress.start_phase(PROGFRAC_PREP, default());
+
     let mut walk = WalkDir::new(&file)
       .same_file_system(true)
       .follow_links(true)
@@ -34,14 +40,17 @@ impl BundleForUpload {
     };
     if ! peek.file_type().is_dir() {
       let f = File::open(&file).context("open")?;
-      Self::prepare_open_file(&file, f)?
+      Self::prepare_open_file(&file, progress, f)?
     } else {
-      Self::prepare_from_dir(&file, walk)?
+      Self::prepare_from_dir(&file, progress, walk)?
     }
   }
 
   #[throws(AE)]
-  pub fn prepare_open_file(file: &str, f: File) -> Self {
+  pub fn prepare_open_file(file: &str, progress: &mut termprogress::Nest,
+                           f: File) -> Self {
+    progress.start_phase(PROGFRAC_HASH, default());
+
     let size = f
       .metadata().context("fstat bundle file")?
       .len()
@@ -75,7 +84,8 @@ impl BundleForUpload {
   }
 
   #[throws(AE)]
-  pub fn prepare_from_dir<W>(dir: &str, walk: W) -> Self
+  pub fn prepare_from_dir<W>(dir: &str, progress: &mut termprogress::Nest,
+                             walk: W) -> Self
   where W: Iterator<Item=walkdir::Result<walkdir::DirEntry>>
   {
     let zipfile = tempfile::tempfile().context("create tmp zipfile")?;
@@ -129,7 +139,7 @@ impl BundleForUpload {
       .map_err(|e| e.into_error()).context("flush zipfile")?;
     zipfile.rewind().context("rewind zipfile")?;
 
-    Self::prepare_open_file(dir, zipfile)?
+    Self::prepare_open_file(dir,progress, zipfile)?
   }
 }
 
@@ -153,9 +163,12 @@ mod upload_bundle {
   fn call(SCCA{ mut out, ma, args,.. }:SCCA) {
     let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
     let mut chan = ma.access_game()?;
-    let mut progress = ma.progressbar()?;
-    let for_upload = BundleForUpload::prepare(args.bundle_file)?;
-    let bundle = for_upload.upload(&ma, &mut chan, &mut *progress)?;
+    let progress = ma.progressbar()?;
+    let mut progress = termprogress::Nest::new(progress);
+
+    let for_upload = BundleForUpload::prepare(args.bundle_file,
+                                              &mut progress)?;
+    let bundle = for_upload.upload(&ma, &mut chan, &mut progress)?;
     writeln!(out, "{}", bundle)?;
   }
 
index 5082cd4477ec04c3c9b380f9a454a9f2f0cd2f70..c618b46845c776bef9e863709178ca61506640ae 100644 (file)
@@ -162,6 +162,7 @@ impl Drop for TermReporter {
 }
 
 pub struct Nest {
+  outer_total: f32,
   outer_phase_base: f32,
   outer_phase_size: f32,
   desc_prefix: String,
@@ -169,10 +170,19 @@ pub struct Nest {
 }
 
 impl Nest {
-  /// Assumes that every inner phase is of the same length as the first
   pub fn new(actual_reporter: Box<dyn Reporter>)
              -> Self { Nest {
     actual_reporter,
+    outer_total: 1.,
+    outer_phase_base: 0.,
+    outer_phase_size: 0.,
+    desc_prefix: default(),
+  } }
+
+  pub fn with_total(outer_total: f32, actual_reporter: Box<dyn Reporter>)
+             -> Self { Nest {
+    actual_reporter,
+    outer_total,
     outer_phase_base: 0.,
     outer_phase_size: 0.,
     desc_prefix: default(),
@@ -193,8 +203,8 @@ impl Reporter for Nest {
   fn report(&mut self, inner_pi: &ProgressInfo<'_>) {
     let inner_frac = inner_pi.phase.value.fraction();
     let outer_frac =
-      self.outer_phase_size * inner_frac +
-      self.outer_phase_base;
+      (self.outer_phase_size * inner_frac +
+       self.outer_phase_base) / self.outer_total;
 
     let desc = if self.desc_prefix != "" {
       format!("{} {}", &self.desc_prefix, inner_pi.phase.desc).into()