Skip to content
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

Generalized progress API (for download etc.) #8064

Closed
ihnorton opened this issue Aug 20, 2014 · 22 comments
Closed

Generalized progress API (for download etc.) #8064

ihnorton opened this issue Aug 20, 2014 · 22 comments

Comments

@ihnorton
Copy link
Member

From JuliaLang/IJulia.jl#211:

@stevengj

I wish that the download function had an option to display some kind of progress indicator, but I agree that at a minimum we should print out some status updates for a long build.

@StefanKarpinski

In general, I think we need a standard pattern for functions that might or might not want to present updates. One thing that comes to mind is having a status::Callable=(args...)->nothing keyword argument that defaults to ignoring status updates.

@vtjnash

@StefanKarpinski that sounds a lot like the Julia-side of the libuv-API (esp. for Process) pre-Jeff's cleanup to use Tasks rather than status callback functions :)

@ihnorton
Copy link
Member Author

My $.02: I like the iterator-style design of @timholy's https://github.com/timholy/ProgressMeter.jl ... I think bringing that into base with a generalization to a display-style stack would be ideal, so that IJulia and all the rest can provide hooks as appropriate.

@tknopp
Copy link
Contributor

tknopp commented Aug 20, 2014

Yes ProgressMeter.jl is really nice. Was so happy when I first discovered it. Would be great to make the architecture general enough that one potentially could plug a Gtk progress bar to it when programming a GUI with Gtk.jl.

@ivarne
Copy link
Sponsor Member

ivarne commented Aug 20, 2014

Why not just let IJulia depend on ProgressMeter.jl, and help make it better where it is?

@timholy
Copy link
Sponsor Member

timholy commented Aug 20, 2014

Why not just let IJulia depend on ProgressMeter.jl, and help make it better where it is?

Base's download function would have to depend on it. Or of course IJulia could rewrite the download function.

I think bringing that into base with a generalization to a display-style stack would be ideal, so that IJulia and all the rest can provide hooks as appropriate.

I'm fine either way. Will submit a PR if it seems there is sufficient interest, but it does seem worth exploring whether it would be usable to leave it as a package.

@stevengj
Copy link
Member

For something like this to work in IPython, I think it would have to hook into the new interactive-widget stuff (cc @shashi).

@shashi
Copy link
Contributor

shashi commented Aug 20, 2014

Here is the code you can use to show a progress bar in IJulia:

using React, Interact
i = Input(0)
@lift Progress(value=i) # you can specify range::Range kwarg for a range. It's 0:100 by default
push!(i, 20) # Set the progress to 20%. Should probably do this with @async inside an event loop.

i could be substituted with any Signal of Integers. E.g.

using React, Interact
s = Slider(0:100)
@lift Progress(value=signal(s))

This will give you a slider and sync its value with that of the progress bar. One should be able to write counterparts to Interact widgets (Progess is one of them) in Gtk, and have something similar.

@StefanKarpinski
Copy link
Sponsor Member

I kind of like that line of thought but I'm not sure we really want to be updating on every iteration.

@shashi
Copy link
Contributor

shashi commented Aug 20, 2014

Ah, I don't know the entire context here, but calling @async push!(i, <progress>) whenever you want to update the progress would do that. You can use @lift Progress(value=droprepeats(i)) to only update the progress widget if i has changed since the last update. This is cheap. In fact updating the progress is cheap too. The progress widget is not actually redrawn, just updated.

@timholy
Copy link
Sponsor Member

timholy commented Aug 20, 2014

Perhaps we should see if we can integrate this with ProgressMeter, which is smart enough (1) to update no more frequently than some specified temporal interval, and (2) not display anything at all if the calculation finishes before the first interval expires, but (3) doesn't force the user to think about any of this stuff (you notify ProgressMeter of incremental progress, and it decides whether to update the display).

@shashi
Copy link
Contributor

shashi commented Aug 20, 2014

I just tried out ProgressMeter. That's very useful!!

I tried making my React example more feature rich, I like how it reads :D :

using React, React.Timing
function progress(n, dt)
   t0 = time()
   ticks = every(dt)
   input = Input(nothing)
   count = foldl((a, b) -> a+1, 0, input)
   completed = @lift droprepeats(sampleon(ticks, count)) / n * 100
   eta = @lift (ticks - t0) * (100 - completed) / 100
   input, completed, eta
   # you can push!(input, nothing) to increment count
   # completed holds the % completed
   # eta is the ETA
end

This has a few issues: 1) ticks never stops updating (React lacks this feature now. I'll fix that.) 2) I don't know how I could not update anything at all if the calculation finishes within dt, but could find a way.

ProgressMeter looks self sufficient though. OTOH, I will do a PR integrating ProgressMeter with Interact's progress bar so that ProgressMeter is prettier on IJulia.

@StefanKarpinski
Copy link
Sponsor Member

The algorithm side should also not need to care whether there is a) no way to output any progress, b) only a text terminal, or c) it's in IJulia or some other rich environment. It would also be great to be able to retroactively decide that you want to connect to something that's ongoing and see its progress – how many times haven't we all regretted not turning on progress output when trying to figure out if some long-running computation is hung or just taking a really long time.

@timholy
Copy link
Sponsor Member

timholy commented Aug 20, 2014

The retroactive thing would be great, but honestly I have no idea how to pull that off. Perhaps by disassembling the code_native output it would be possible, but I think that officially counts as heroics.

@Keno
Copy link
Member

Keno commented Aug 20, 2014

Adding it to the TODO list ;)

@timholy
Copy link
Sponsor Member

timholy commented Aug 20, 2014

I just checked my English-to-Julian dictionary, and it turns out that "Keno" actually means "heroic." Will coincidences never cease...

@Keno
Copy link
Member

Keno commented Aug 20, 2014

Seriously though, this will be pretty easy to do with the debugging stuff I'm working on.

@timholy
Copy link
Sponsor Member

timholy commented Aug 20, 2014

That will be amazing.

@c42f
Copy link
Member

c42f commented Apr 15, 2017

I just came across this old issue. I'm thinking about the best way to build this into MicroLogging, as I think progress reporting is not very different from other types of logging. The current idea is that it's just a progress key in a standard structured log record:

for i=1:100
    sleep(0.01)
    @info "Algorithm 1" progress=i/100
end

This way the user specified logger gets to decide how to display progress messages - or filter them as desired - and they can interact properly with other non-progress log messages. It's a proof of concept still, but seems to be turning out quite naturally.

@c42f c42f mentioned this issue Dec 15, 2017
15 tasks
@pfitzseb
Copy link
Member

Juno will have something like this on 0.7 (see here); should be rather easy to have ProgressMeter.jl conform to a simliar API.

@cossio
Copy link
Contributor

cossio commented Feb 29, 2020

Any updates on this? Particularly for Base.download(...), is there a way to print progress (in Juno, IJulia, or the REPL)?

@StefanKarpinski
Copy link
Sponsor Member

No, since it uses various external programs which don’t have a consistent way of reporting progress. However, we would like to replace that approach with a native Julia implementation which could report progress.

@c42f
Copy link
Member

c42f commented Mar 2, 2020

The logging-based progress APIs have been improving lately.

With https://github.com/JunoLab/ProgressLogging.jl for the frontend and https://github.com/c42f/TerminalLoggers.jl for the in-terminal formatting I think we've getting close to a slick solution (see demo at JuliaLogging/TerminalLoggers.jl#13)

@KristofferC
Copy link
Sponsor Member

I think the logging system has enough of this now to facilitate writing frontend progress bars based on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests