diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-01-05 12:54:53 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-01-05 14:05:37 +0200 |
commit | 8a42fc1c9dc3da6936fe8e1d0d16fbe8a60ec520 (patch) | |
tree | 7c2d38852e6f1eec5c357b2304a04dc332b8d953 /src/backup_run.rs | |
parent | 678e65c57ae983ef66d16e92965814b0f3f0d73f (diff) | |
download | obnam2-8a42fc1c9dc3da6936fe8e1d0d16fbe8a60ec520.tar.gz |
refactor: move policy on whether to back up a file into a module
This commit also splits up the src/cmd/backup.rs module into other,
smaller, more cohesive modules that are easier to understand and use.
Diffstat (limited to 'src/backup_run.rs')
-rw-r--r-- | src/backup_run.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/backup_run.rs b/src/backup_run.rs new file mode 100644 index 0000000..e3bfc5a --- /dev/null +++ b/src/backup_run.rs @@ -0,0 +1,92 @@ +use crate::backup_progress::BackupProgress; +use crate::backup_reason::Reason; +use crate::chunkid::ChunkId; +use crate::client::{BackupClient, ClientConfig}; +use crate::fsentry::FilesystemEntry; +use crate::generation::LocalGeneration; +use crate::policy::BackupPolicy; +use log::{info, warn}; + +pub struct BackupRun { + client: BackupClient, + policy: BackupPolicy, + buffer_size: usize, + progress: BackupProgress, +} + +impl BackupRun { + pub fn new(config: &ClientConfig, buffer_size: usize) -> anyhow::Result<Self> { + let client = BackupClient::new(&config.server_url)?; + let policy = BackupPolicy::new(); + let progress = BackupProgress::new(); + Ok(Self { + client, + policy, + buffer_size, + progress, + }) + } + + pub fn client(&self) -> &BackupClient { + &self.client + } + + pub fn progress(&self) -> &BackupProgress { + &self.progress + } + + pub fn backup_file_initially( + &self, + entry: anyhow::Result<FilesystemEntry>, + ) -> anyhow::Result<(FilesystemEntry, Vec<ChunkId>, Reason)> { + match entry { + Err(err) => Err(err.into()), + Ok(entry) => { + let path = &entry.pathbuf(); + info!("backup: {}", path.display()); + self.progress.found_live_file(path); + let ids = self + .client + .upload_filesystem_entry(&entry, self.buffer_size)?; + Ok((entry.clone(), ids, Reason::IsNew)) + } + } + } + + pub fn backup_file_incrementally( + &self, + entry: anyhow::Result<FilesystemEntry>, + old: &LocalGeneration, + ) -> anyhow::Result<(FilesystemEntry, Vec<ChunkId>, Reason)> { + match entry { + Err(err) => { + warn!("backup: {}", err); + self.progress.found_problem(); + Err(err) + } + Ok(entry) => { + let path = &entry.pathbuf(); + info!("backup: {}", path.display()); + self.progress.found_live_file(path); + let reason = self.policy.needs_backup(&old, &entry); + match reason { + Reason::IsNew | Reason::Changed | Reason::Error => { + let ids = self + .client + .upload_filesystem_entry(&entry, self.buffer_size)?; + Ok((entry.clone(), ids, reason)) + } + Reason::Unchanged | Reason::Skipped => { + let fileno = old.get_fileno(&entry.pathbuf())?; + let ids = if let Some(fileno) = fileno { + old.chunkids(fileno)? + } else { + vec![] + }; + Ok((entry.clone(), ids, reason)) + } + } + } + } + } +} |