timholy / ProgressMeter.jl

Progress meter for long-running computations
MIT License
694 stars 91 forks source link

Progress output is mangled when using `async` #253

Closed arnaudh closed 2 months ago

arnaudh commented 1 year ago
using ProgressMeter
progress = Progress(10);
asyncmap(1:10) do i
   sleep(i*0.1)
   next!(progress)
end

Output:

Progress:  20%|███████████▍                                             |  ETA: 0:00:04Progress:  30%|█████████████████▏                                       |  ETA: 0:00:03Progress:  40%|██████████████████████▊                                  |  ETA: 0:00:02Progress:  50%|████████████████████████████▌                            |  ETA: 0:00:01Progress:  60%|██████████████████████████████████▎                      |  ETA: 0:00:01Progress:  70%|███████████████████████████████████████▉                 |  ETA: 0:00:01Progress:  80%|███████████████████████████████████████Progress: 100%|█████████████████████████████████████████████████████████| Time: 0:00:01

Seems like the line doesn't get properly cleared/overriden when multiple calls to next!(progress) happen concurrently.

Note if I bump the sleep to a higher value (sleep(i)), the issue goes away:

Progress: 100%|█████████████████████████████████████████████████████████| Time: 0:00:10
arnaudh commented 1 year ago

Had a quick look at the code and documentation, seems like @showprogress can work with asyncmap, and a quick test shows the issue is not present in that case:

@showprogress asyncmap(1:10) do i
   sleep(i*0.1)
end

Output:

Progress: 100%|█████████████████████████████████████████████████████████| Time: 0:00:02

Sounds like this is the way to go.

Note I assumed my example (using ayncmap and next!) would be supported because of the note on thread-safety in the README (with the example using @threads and next!). Might be worth mentioning that asyncmap is only supported via @showprogress.

MarcMush commented 1 year ago

The problem appears when two parallel tasks try to erase and write at the same time

Using next! with a ParallelProgress will be possible with #157

MarcMush commented 2 months ago

this should now work by forcing the lock (Progress(10; safe_lock=true)) (#322)