11// Copyright 2019-2025 ChainSafe Systems
22// SPDX-License-Identifier: Apache-2.0, MIT
33
4- use super :: * ;
54use crate :: chain:: FilecoinSnapshotVersion ;
65use crate :: chain_sync:: SyncConfig ;
76use crate :: cli_shared:: snapshot:: { self , TrustedVendor } ;
@@ -11,11 +10,10 @@ use crate::rpc::{self, chain::ForestChainExportParams, prelude::*, types::ApiTip
1110use anyhow:: Context as _;
1211use chrono:: DateTime ;
1312use clap:: Subcommand ;
14- use human_repr:: HumanCount ;
15- use num:: Zero as _;
13+ use indicatif:: { ProgressBar , ProgressStyle } ;
1614use std:: {
1715 path:: { Path , PathBuf } ,
18- time:: { Duration , Instant } ,
16+ time:: Duration ,
1917} ;
2018use tokio:: io:: AsyncWriteExt ;
2119
@@ -99,48 +97,36 @@ impl SnapshotCommands {
9997 dry_run,
10098 } ;
10199
100+ let pb = ProgressBar :: new_spinner ( ) . with_style (
101+ ProgressStyle :: with_template (
102+ "{spinner} {msg} {binary_total_bytes} written in {elapsed} ({binary_bytes_per_sec})" ,
103+ )
104+ . expect ( "indicatif template must be valid" ) ,
105+ ) . with_message ( format ! ( "Exporting {} ..." , output_path. display( ) ) ) ;
106+ pb. enable_steady_tick ( std:: time:: Duration :: from_millis ( 80 ) ) ;
102107 let handle = tokio:: spawn ( {
103- let start = Instant :: now ( ) ;
104- let tmp_file = temp_path . to_owned ( ) ;
105- let output_path = output_path . clone ( ) ;
108+ let path : PathBuf = ( & temp_path ) . into ( ) ;
109+ let pb = pb . clone ( ) ;
110+ let mut interval = tokio :: time :: interval ( tokio :: time :: Duration :: from_secs ( 1 ) ) ;
106111 async move {
107- let mut interval =
108- tokio:: time:: interval ( tokio:: time:: Duration :: from_secs_f32 ( 0.5 ) ) ;
109- println ! ( "Getting ready to export..." ) ;
110112 loop {
111113 interval. tick ( ) . await ;
112- let snapshot_size = std:: fs:: metadata ( & tmp_file)
113- . map ( |meta| meta. len ( ) )
114- . unwrap_or ( 0 ) ;
115- print ! (
116- "{}{}" ,
117- anes:: MoveCursorToPreviousLine ( 1 ) ,
118- anes:: ClearLine :: All
119- ) ;
120- let elapsed_secs = start. elapsed ( ) . as_secs_f64 ( ) ;
121- println ! (
122- "{}: {} ({}/s)" ,
123- & output_path. to_string_lossy( ) ,
124- snapshot_size. human_count_bytes( ) ,
125- if elapsed_secs. is_zero( ) {
126- 0.
127- } else {
128- ( snapshot_size as f64 ) / elapsed_secs
129- }
130- . human_count_bytes( ) ,
131- ) ;
132- let _ = std:: io:: stdout ( ) . flush ( ) ;
114+ if let Ok ( meta) = std:: fs:: metadata ( & path) {
115+ pb. set_position ( meta. len ( ) ) ;
116+ }
133117 }
134118 }
135119 } ) ;
120+
136121 // Manually construct RpcRequest because snapshot export could
137122 // take a few hours on mainnet
138123 let hash_result = client
139124 . call ( ForestChainExport :: request ( ( params, ) ) ?. with_timeout ( Duration :: MAX ) )
140125 . await ?;
141126
142127 handle. abort ( ) ;
143- let _ = handle. await ;
128+ pb. finish ( ) ;
129+ _ = handle. await ;
144130
145131 if let Some ( hash) = hash_result {
146132 save_checksum ( & output_path, hash) . await ?;
0 commit comments