feat: add progress bars to sync and store init (#1684)

Replace lots of logging with some progress bars. This looks much nicer

I'd like to move it out of the atuin-client crate and into the atuin
crate. But first, I want to decouple a lot of the record moving, so it
can wait until that's done.
This commit is contained in:
Ellie Huxtable 2024-02-08 13:34:41 +00:00 committed by GitHub
parent 1993653102
commit 8460210202
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 17 deletions

1
Cargo.lock generated
View File

@ -237,6 +237,7 @@ dependencies = [
"futures", "futures",
"generic-array", "generic-array",
"hex", "hex",
"indicatif",
"interim", "interim",
"itertools", "itertools",
"lazy_static", "lazy_static",

View File

@ -67,6 +67,7 @@ urlencoding = { version = "2.1.0", optional = true }
reqwest = { workspace = true, optional = true } reqwest = { workspace = true, optional = true }
hex = { version = "0.4", optional = true } hex = { version = "0.4", optional = true }
sha2 = { version = "0.10", optional = true } sha2 = { version = "0.10", optional = true }
indicatif = "0.17.7"
[dev-dependencies] [dev-dependencies]
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }

View File

@ -1,6 +1,7 @@
use std::collections::HashSet; use std::{collections::HashSet, fmt::Write};
use eyre::{bail, eyre, Result}; use eyre::{bail, eyre, Result};
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use rmp::decode::Bytes; use rmp::decode::Bytes;
use crate::{ use crate::{
@ -263,11 +264,17 @@ impl HistoryStore {
println!("Fetching history already in store"); println!("Fetching history already in store");
let store_ids = self.history_ids().await?; let store_ids = self.history_ids().await?;
let pb = ProgressBar::new(history.len() as u64);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {human_pos}/{human_len} ({eta})")
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));
for i in history { for i in history {
println!("loaded {}", i.id); debug!("loaded {}", i.id);
if store_ids.contains(&i.id) { if store_ids.contains(&i.id) {
println!("skipping {} - already exists", i.id); debug!("skipping {} - already exists", i.id);
continue; continue;
} }
@ -277,8 +284,12 @@ impl HistoryStore {
} else { } else {
self.push(i).await?; self.push(i).await?;
} }
pb.inc(1);
} }
pb.finish_with_message("Import complete");
Ok(()) Ok(())
} }
} }

View File

@ -1,5 +1,5 @@
// do a sync :O // do a sync :O
use std::cmp::Ordering; use std::{cmp::Ordering, fmt::Write};
use eyre::Result; use eyre::Result;
use thiserror::Error; use thiserror::Error;
@ -8,6 +8,7 @@ use super::store::Store;
use crate::{api_client::Client, settings::Settings}; use crate::{api_client::Client, settings::Settings};
use atuin_common::record::{Diff, HostId, RecordId, RecordIdx, RecordStatus}; use atuin_common::record::{Diff, HostId, RecordId, RecordIdx, RecordStatus};
use indicatif::{ProgressBar, ProgressState, ProgressStyle};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum SyncError { pub enum SyncError {
@ -165,6 +166,12 @@ async fn sync_upload(
let upload_page_size = 100; let upload_page_size = 100;
let mut progress = 0; let mut progress = 0;
let pb = ProgressBar::new(expected);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {human_pos}/{human_len} ({eta})")
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));
println!( println!(
"Uploading {} records to {}/{}", "Uploading {} records to {}/{}",
expected, expected,
@ -189,12 +196,7 @@ async fn sync_upload(
SyncError::RemoteRequestError { msg: e.to_string() } SyncError::RemoteRequestError { msg: e.to_string() }
})?; })?;
println!( pb.set_position(progress);
"uploaded {} to remote, progress {}/{}",
page.len(),
progress,
expected
);
progress += page.len() as u64; progress += page.len() as u64;
if progress >= expected { if progress >= expected {
@ -202,6 +204,8 @@ async fn sync_upload(
} }
} }
pb.finish_with_message("Uploaded records");
Ok(progress as i64) Ok(progress as i64)
} }
@ -226,6 +230,12 @@ async fn sync_download(
tag tag
); );
let pb = ProgressBar::new(expected);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {human_pos}/{human_len} ({eta})")
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));
// preload with the first entry if remote does not know of this store // preload with the first entry if remote does not know of this store
loop { loop {
let page = client let page = client
@ -238,15 +248,9 @@ async fn sync_download(
.await .await
.map_err(|e| SyncError::LocalStoreError { msg: e.to_string() })?; .map_err(|e| SyncError::LocalStoreError { msg: e.to_string() })?;
println!(
"downloaded {} records from remote, progress {}/{}",
page.len(),
progress,
expected
);
ret.extend(page.iter().map(|f| f.id)); ret.extend(page.iter().map(|f| f.id));
pb.set_position(progress);
progress += page.len() as u64; progress += page.len() as u64;
if progress >= expected { if progress >= expected {
@ -254,6 +258,8 @@ async fn sync_download(
} }
} }
pb.finish_with_message("Downloaded records");
Ok(ret) Ok(ret)
} }