From 7540f7e051047f85d50bbe7ac0cbf5e11c32aaef Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Tue, 23 Feb 2021 09:04:05 +0200 Subject: feat: have separate progress bar for each backup phase --- client.yaml | 2 +- src/backup_progress.rs | 26 ++++++++++++++++++++++++++ src/backup_run.rs | 50 +++++++++++++++++++++++++++++++++++++++++--------- src/cmd/backup.rs | 16 ++++++++-------- 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/client.yaml b/client.yaml index aead475..7fa935b 100644 --- a/client.yaml +++ b/client.yaml @@ -1,5 +1,5 @@ server_url: https://localhost:8888 verify_tls_cert: false roots: - - /home/liw/tmp/irregular + - /home/liw/tmp/watch-and-review log: obnam.log diff --git a/src/backup_progress.rs b/src/backup_progress.rs index c6d16d9..6035eff 100644 --- a/src/backup_progress.rs +++ b/src/backup_progress.rs @@ -45,6 +45,32 @@ impl BackupProgress { Self { progress } } + pub fn upload_generation() -> Self { + let progress = ProgressBar::new(0); + let parts = vec![ + "uploading new generation metadata", + "elapsed: {elapsed}", + "{spinner}", + ]; + progress.set_style(ProgressStyle::default_bar().template(&parts.join("\n"))); + progress.enable_steady_tick(100); + + Self { progress } + } + + pub fn download_generation(gen_id: &str) -> Self { + let progress = ProgressBar::new(0); + let parts = vec!["{msg}", "elapsed: {elapsed}", "{spinner}"]; + progress.set_style(ProgressStyle::default_bar().template(&parts.join("\n"))); + progress.enable_steady_tick(100); + progress.set_message(&format!( + "downloading previous generation metadata: {}", + gen_id + )); + + Self { progress } + } + pub fn files_in_previous_generation(&self, count: u64) { self.progress.set_length(count); } diff --git a/src/backup_run.rs b/src/backup_run.rs index 60623e6..ea5888a 100644 --- a/src/backup_run.rs +++ b/src/backup_run.rs @@ -2,6 +2,7 @@ use crate::backup_progress::BackupProgress; use crate::backup_reason::Reason; use crate::chunkid::ChunkId; use crate::client::{BackupClient, ClientConfig, ClientError}; +use crate::error::ObnamError; use crate::fsentry::FilesystemEntry; use crate::fsiter::{FsIterError, FsIterResult}; use crate::generation::{LocalGeneration, LocalGenerationError}; @@ -19,7 +20,7 @@ pub struct IncrementalBackup<'a> { client: &'a BackupClient, policy: BackupPolicy, buffer_size: usize, - progress: BackupProgress, + progress: Option, } #[derive(Debug, thiserror::Error)] @@ -46,8 +47,8 @@ impl<'a> InitialBackup<'a> { }) } - pub fn progress(&self) -> &BackupProgress { - &self.progress + pub fn drop(&self) { + &self.progress.finish(); } pub fn backup( @@ -73,21 +74,40 @@ impl<'a> InitialBackup<'a> { impl<'a> IncrementalBackup<'a> { pub fn new(config: &ClientConfig, client: &'a BackupClient) -> BackupResult { let policy = BackupPolicy::new(); - let progress = BackupProgress::incremental(); Ok(Self { client, policy, buffer_size: config.chunk_size, - progress, + progress: None, }) } + pub fn start_backup(&mut self, old: &LocalGeneration) -> Result<(), ObnamError> { + let progress = BackupProgress::incremental(); + progress.files_in_previous_generation(old.file_count()? as u64); + self.progress = Some(progress); + Ok(()) + } + pub fn client(&self) -> &BackupClient { self.client } - pub fn progress(&self) -> &BackupProgress { - &self.progress + pub fn drop(&self) { + if let Some(progress) = &self.progress { + progress.finish(); + } + } + + pub fn fetch_previous_generation( + &self, + genid: &str, + oldname: &Path, + ) -> Result { + let progress = BackupProgress::download_generation(genid); + let old = self.client().fetch_generation(genid, &oldname)?; + progress.finish(); + Ok(old) } pub fn backup( @@ -98,13 +118,13 @@ impl<'a> IncrementalBackup<'a> { match entry { Err(err) => { warn!("backup: {}", err); - self.progress.found_problem(); + self.found_problem(); Err(BackupError::FsIterError(err)) } Ok(entry) => { let path = &entry.pathbuf(); info!("backup: {}", path.display()); - self.progress.found_live_file(path); + self.found_live_file(path); let reason = self.policy.needs_backup(&old, &entry); match reason { Reason::IsNew @@ -126,6 +146,18 @@ impl<'a> IncrementalBackup<'a> { } } } + + fn found_live_file(&self, path: &Path) { + if let Some(progress) = &self.progress { + progress.found_live_file(path); + } + } + + fn found_problem(&self) { + if let Some(progress) = &self.progress { + progress.found_problem(); + } + } } fn backup_file( diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs index 3f2d7d4..94b8761 100644 --- a/src/cmd/backup.rs +++ b/src/cmd/backup.rs @@ -1,3 +1,4 @@ +use crate::backup_progress::BackupProgress; use crate::backup_run::{IncrementalBackup, InitialBackup}; use crate::chunkid::ChunkId; use crate::client::{BackupClient, ClientConfig}; @@ -37,20 +38,20 @@ pub fn backup(config: &ClientConfig) -> Result<(), ObnamError> { Err(_) => { let run = InitialBackup::new(config, &client)?; let count = initial_backup(&config.roots, &newname, &run)?; - run.progress().finish(); count } Ok(old) => { - let run = IncrementalBackup::new(config, &client)?; - let count = incremental_backup(&old, &config.roots, &newname, &oldname, &run)?; - run.progress().finish(); + let mut run = IncrementalBackup::new(config, &client)?; + let count = incremental_backup(&old, &config.roots, &newname, &oldname, &mut run)?; count } }; // Upload the SQLite file, i.e., the named temporary file, which // still exists, since we persisted it above. + let progress = BackupProgress::upload_generation(); let gen_id = client.upload_generation(&newname, SQLITE_CHUNK_SIZE)?; + progress.finish(); // Delete the temporary file.q std::fs::remove_file(&newname)?; @@ -89,16 +90,15 @@ fn incremental_backup( roots: &[PathBuf], newname: &Path, oldname: &Path, - run: &IncrementalBackup, + run: &mut IncrementalBackup, ) -> Result { info!("incremental backup based on {}", old); - let old = run.client().fetch_generation(&old, &oldname)?; + let old = run.fetch_previous_generation(old, oldname)?; + run.start_backup(&old)?; let mut new = NascentGeneration::create(&newname)?; for root in roots { let iter = FsIterator::new(root); - run.progress() - .files_in_previous_generation(old.file_count()? as u64); new.insert_iter(iter.map(|entry| run.backup(entry, &old)))?; } Ok(new.file_count()) -- cgit v1.2.1