-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: progress bar for iroh add command #368
Conversation
I've experimented using |
Note to self: I need to check whether I really caught all call sites of add_file, I think I may have missed one in the gateway. Need to provide a consuming version for that place and benchmark code. Edit: I checked and this is a false alarm; this |
At least on the mac, things start getting weird if you resize the terminal window to a smaller size than the width of the text. If your terminal is already less wide than the text on startup, the delete does not work and you get one line per update: Not sure if you can do anything about that, just wanted to mention it... I guess we should assume 80 characters per line, and never exceed that to avoid running into such problems. If somebody has a tiny terminal they just have to live with it. Is it possible to disable this in this case? |
So as far as the API changes are concerned:
|
/// An event on the add stream | ||
pub enum AddEvent { | ||
/// Delta of progress in bytes | ||
ProgressDelta(u64), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned yesterday, if this event could be made self-contained you could use something like a tokio watch channel to drop progress updates. https://docs.rs/tokio/latest/tokio/sync/watch/index.html
But not the end of the world.
It would be nice to have a bit more information here. E.g. the number of objects and the number of bytes. E.g. if you are adding lots of small files you won't see much progress in terms of bytes, but there is still something happening.
Does not have to happen in this PR though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really get yet how you see using the watch channel. You mean it should keep a count of the total amount of bytes too somewhere here? That doesn't really work well with the progress bar inc()
approach, and I'd have to introduce code to introduce a total. Transforming a stream seems simpler to me.
By the "number of objects" do you mean the number of files and such? Getting the file path information is something I want to do as I mentioned in the PR, but it's a bit of an effort and I think I should focus on lower hanging fruit for now.
What do you mean by the number of bytes? The number of bytes is reported here in the u64
so I don't get what you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by the number of bytes?
Yes, the number of bytes we have, but the number of files would be nice in addition. Just so you could show how many files have been added when adding a large directory full of small files like the linux kernel. But as you said, it can happen later.
I don't really get yet how you see using the watch channel
Imagine drawing the progress information takes some time, and you push a lot of updates over the channel. Then actually drawing the progress info would slow things down. What you would want to do is to "debounce" (I think that's what they call it in frontend land) the drawing so it happens only at a reasonable rate.
But you can not do this because you need every single event in th eupdate channel. But no big deal, you could compute the aggregate and then debounce that stream using tokio watch.
Why does it make it more annoying to use? What could I return instead? Is the problem that they're |
As soon as you are in async land, basically the default case is that your streams and futures can be polled from any thread (aka are Send). Now, this is sometimes not necessary, e.g. if you have a single threaded executor. But this is not captured in the type system. I am suffering from this all week because some parts of the rocksdb binding are not Send, so it is a pain to use in async. E.g. fn main() {
// a local future
let f = async { "whatever" }.boxed_local();
//
tokio::task::spawn(|| async move {
let x = f.await; // does not work because f is not Send
});
} Now take a look at our codebase and you will see that spawning a task is a very frequent thing in typical async code... Whether that is a good thing or not I won't comment on, it's just how it is. So an API that only has local futures and streams will be an api that people hate...
I did a quick check. The non send requirement kinda bubbles up from the bottom, but it is just a few places where you would have to require Send. Here is a commit that adds Send and friends in a few places to allow the API to be Send: rklaehn@59bc0b5 Now if we should do that I have no idea, I guess we would have to have a longer discussion. But this is what we would have to do. Ping @dignifiedquire |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked the progress bar again. Seems to work well now.
Don't want visual glitches
d3056b0
to
8fbb263
Compare
Let's continue the |
This introduces a progress bar for the
iroh add
command. It touches the following layers:the various
add_dir
,add_file
functions iniroh::resolver::unixfs_builder
now return a stream ofAddEvents
these are exposed in the
iroh-api
where they are mockable. Theiroh-api
also provides a higher level method to resolve aAddEvent
stream to a CIDiroh::size
introduces a way to calculate total size of each file on the filesystemThe
iroh add
command in theiroh
crate then calculates the total size with a spinner, and then uses this to show a progress bar.Note that
indicatif
, the progress bar library, allows a lot of tweaking of what we see, both color, characters and text. I made a selection to get started. Suggestions for tweaks of what the bar looks like are welcome.I will create a follow-up PR where I add a "current file" indicator in the progress bar, but I think this is already major progress so didn't want to hold back merging. Update Getting current file information requires quite a lot of changes inside
unixfs_builder
with some open questions, so I am going defer the creation of this follow-up PR until later and focus on earlier wins.