Skip to content

Commit 38b33b9

Browse files
fix: messy progress bar in dump_range (#155)
* fix: use multi progress * improve * fmt --------- Co-authored-by: Akase Haruka <[email protected]> Co-authored-by: lightsing <[email protected]>
1 parent da3269b commit 38b33b9

File tree

2 files changed

+101
-61
lines changed

2 files changed

+101
-61
lines changed

crates/bin/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ console.workspace = true
2828
indicatif.workspace = true
2929
serde_json.workspace = true
3030
serde_path_to_error.workspace = true
31-
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
31+
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs"] }
3232
url.workspace = true
3333
tracing = { workspace = true, optional = true }
3434

crates/bin/src/dump.rs

Lines changed: 100 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
use crate::helpers::{NumberOrRange, RpcArgs};
12
use alloy::providers::RootProvider;
23
use clap::Args;
3-
use console::{Emoji, style};
4-
use eyre::Context;
5-
use indicatif::{HumanBytes, HumanDuration, ProgressBar, ProgressStyle};
4+
use console::Emoji;
5+
use eyre::{Context, ContextCompat};
6+
use indicatif::{HumanBytes, HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
67
use sbv::{primitives::types::Network, utils::rpc::ProviderExt};
78
use std::{
8-
path::PathBuf,
9+
collections::HashMap,
10+
path::{Path, PathBuf},
11+
sync::LazyLock,
912
time::{Duration, Instant},
1013
};
1114

12-
use crate::helpers::{NumberOrRange, RpcArgs};
15+
const INFO_ICON: Emoji = Emoji(" 🔗 ", " [+] ");
16+
const ERR_ICON: Emoji = Emoji(" ❌ ", " [x] ");
17+
const COMPLETED_ICON: Emoji = Emoji(" ✅ ", " [v] ");
18+
const SAD_ICON: Emoji = Emoji(" ⚠️ ", " :( ");
19+
const SPARKLE_ICON: Emoji = Emoji(" ✨ ", " :) ");
1320

1421
#[derive(Debug, Args)]
1522
pub struct DumpWitnessCommand {
@@ -44,104 +51,137 @@ impl DumpWitnessCommand {
4451

4552
let provider = self.rpc_args.into_provider();
4653

47-
dump_range(
54+
let ok = dump_range(
4855
provider,
4956
self.block.into(),
5057
self.out_dir,
5158
#[cfg(not(feature = "scroll"))]
5259
self.ancestors,
5360
)
54-
.await?;
61+
.await;
5562

56-
println!(
57-
"{} Done in {}",
58-
Emoji("✨ ", ":-)"),
59-
HumanDuration(started.elapsed())
60-
);
63+
let elapsed = HumanDuration(started.elapsed());
64+
if ok {
65+
println!("{SPARKLE_ICON} Done in {elapsed}");
66+
} else {
67+
println!("{SAD_ICON} Completed with errors in {elapsed}",);
68+
}
6169

6270
Ok(())
6371
}
6472
}
6573

74+
static PB_STYLE: LazyLock<ProgressStyle> =
75+
LazyLock::new(|| ProgressStyle::with_template("{prefix}{msg} {spinner}").expect("infallible"));
76+
6677
async fn dump_range(
6778
provider: RootProvider<Network>,
6879
range: std::ops::Range<u64>,
6980
out_dir: PathBuf,
7081
#[cfg(not(feature = "scroll"))] ancestors: usize,
71-
) -> eyre::Result<()> {
82+
) -> bool {
7283
let mut set = tokio::task::JoinSet::new();
7384

85+
let multi_progress_bar = MultiProgress::new();
86+
87+
let mut ok = true;
88+
let mut pb_map = HashMap::new();
89+
7490
for block in range {
7591
let provider = provider.clone();
7692
let out_dir = out_dir.clone();
77-
set.spawn(async move {
78-
if let Err(e) = dump(
79-
provider,
80-
block,
81-
out_dir.as_path(),
82-
#[cfg(not(feature = "scroll"))]
83-
ancestors,
84-
)
85-
.await
86-
{
87-
eprintln!("Error dumping witness for block {block}: {e}");
88-
}
89-
});
93+
let progress_bar = multi_progress_bar.add(ProgressBar::new_spinner());
94+
let handle = {
95+
let progress_bar = progress_bar.clone();
96+
set.spawn(async move {
97+
dump(
98+
provider,
99+
block,
100+
out_dir.as_path(),
101+
#[cfg(not(feature = "scroll"))]
102+
ancestors,
103+
progress_bar,
104+
)
105+
.await
106+
})
107+
};
108+
pb_map.insert(handle.id(), progress_bar);
90109
}
91110

92-
while let Some(result) = set.join_next().await {
93-
if let Err(e) = result {
94-
eprintln!("Dump task panicked: {e}");
111+
while let Some(result) = set.join_next_with_id().await {
112+
match result {
113+
Err(e) => {
114+
let pb = pb_map.remove(&e.id()).expect("progress bar exists");
115+
pb.set_prefix(format!("{ERR_ICON}"));
116+
pb.finish_with_message(format!("Dump task failed: {e}"));
117+
ok = false;
118+
}
119+
Ok((_, false)) => {
120+
ok = false;
121+
}
122+
_ => { /* ok */ }
95123
}
96124
}
97-
98-
Ok(())
125+
ok
99126
}
100127

101128
async fn dump(
102129
provider: RootProvider<Network>,
103130
block: u64,
104-
out_dir: &std::path::Path,
131+
out_dir: &Path,
105132
#[cfg(not(feature = "scroll"))] ancestors: usize,
106-
) -> eyre::Result<()> {
107-
let pb = ProgressBar::new_spinner();
108-
pb.set_style(ProgressStyle::with_template("{prefix}{msg} {spinner}")?);
109-
pb.set_prefix(format!(
110-
"{} {}",
111-
style("[1/2]").bold().dim(),
112-
Emoji("🔗 ", "")
113-
));
114-
pb.enable_steady_tick(Duration::from_millis(100));
133+
pb: ProgressBar,
134+
) -> bool {
135+
pb.set_style(PB_STYLE.clone());
136+
pb.set_prefix(format!("{INFO_ICON}"));
115137
pb.set_message(format!("Dumping witness for block {block}"));
138+
pb.enable_steady_tick(Duration::from_millis(100));
116139

140+
match dump_inner(
141+
provider,
142+
block,
143+
out_dir,
144+
#[cfg(not(feature = "scroll"))]
145+
ancestors,
146+
)
147+
.await
148+
{
149+
Ok((path, size)) => {
150+
pb.set_prefix(format!("{COMPLETED_ICON}"));
151+
pb.finish_with_message(format!("Witness: {size} saved to {p}", p = path.display()));
152+
true
153+
}
154+
Err(e) => {
155+
pb.set_prefix(format!("{ERR_ICON}"));
156+
pb.finish_with_message(format!("Failed to dump witness for block {block}: {e}"));
157+
false
158+
}
159+
}
160+
}
161+
162+
async fn dump_inner(
163+
provider: RootProvider<Network>,
164+
block: u64,
165+
out_dir: &Path,
166+
#[cfg(not(feature = "scroll"))] ancestors: usize,
167+
) -> eyre::Result<(PathBuf, HumanBytes)> {
117168
#[cfg(not(feature = "scroll"))]
118169
let witness = provider
119170
.dump_block_witness(block)
120171
.ancestors(ancestors)
121172
.send()
122-
.await
123-
.context("dump ethereum block witness")?;
173+
.await?
174+
.context("block not found")?;
124175
#[cfg(feature = "scroll")]
125176
let witness = provider
126177
.dump_block_witness(block)
127178
.send()
128-
.await
129-
.context("dump scroll block witness")?;
130-
131-
pb.finish_with_message(format!("Dumped witness for block {block}"));
132-
println!();
179+
.await?
180+
.context("block not found")?;
133181

134-
let json = serde_json::to_string_pretty(&witness).context("serialize witness")?;
182+
let json = serde_json::to_string_pretty(&witness)?;
135183
let path = out_dir.join(format!("{block}.json"));
136-
std::fs::write(&path, json).context("write json file")?;
137-
let size = HumanBytes(std::fs::metadata(&path)?.len());
138-
println!(
139-
"{} {}JSON witness({}) saved to {}",
140-
style("[2/2]").bold().dim(),
141-
Emoji("📃 ", ""),
142-
size,
143-
path.display()
144-
);
145-
146-
Ok(())
184+
tokio::fs::write(&path, json).await?;
185+
let size = HumanBytes(tokio::fs::metadata(&path).await?.len());
186+
Ok((path, size))
147187
}

0 commit comments

Comments
 (0)