Comments (9)
Should be fixed. If you can test against latest master branch, please do. I didn't test your example thoroughly.
from mpb.
@vbauerster Thanks for the quick response. Alas, this does not fix the issue.
I've distilled my example down to the bare minimum.
// require github.com/vbauerster/mpb/v8 v8.7.1-0.20231205062852-da3162c67234
func main() {
const delay = time.Second * 5
start := time.Now()
delayCh := make(chan struct{})
time.AfterFunc(delay, func() { close(delayCh) })
p := mpb.New(mpb.WithAutoRefresh(), mpb.WithRenderDelay(delayCh))
bar := p.New(0, mpb.BarStyle(), mpb.BarRemoveOnComplete())
bar.Abort(true)
bar.Wait() // <-- blocks here until render delay completes
p.Wait()
fmt.Println("Elapsed: ", time.Since(start))
}
Running this example, you'll see that it blocks on bar.Wait
:
$ go install github.com/neilotoole/mpb-render-delay@latest
$ mpb-render-delay
Elapsed: 5.002145041s
BTW, note that that the behavior is the same with or without mpb.WithAutoRefresh
.
from mpb.
I don't see any wrong behavior here. Render delay is respected correctly, bar is waiting for a reason. If you don't want to wait for a bar don't call bar.Wait()
.
from mpb.
@vbauerster: Even if I skip the bar.Wait()
on the aborted bar, this just pushes the block to p.Wait()
👎.
func main() {
const delay = time.Second * 5
start := time.Now()
delayCh := make(chan struct{})
time.AfterFunc(delay, func() { close(delayCh) })
p := mpb.New(mpb.WithAutoRefresh(), mpb.WithRenderDelay(delayCh))
bar := p.New(0, mpb.BarStyle(), mpb.BarRemoveOnComplete())
bar.Abort(true)
// bar.Wait()
p.Wait() // <-- blocks here until render delay completes
fmt.Println("Elapsed: ", time.Since(start))
}
Why should p.Wait()
continue to block on the render delay, if it has no "alive" bars to wait on?
If we run the example without creating any bars:
func main() {
const delay = time.Second * 5
start := time.Now()
delayCh := make(chan struct{})
time.AfterFunc(delay, func() { close(delayCh) })
p := mpb.New(mpb.WithAutoRefresh(), mpb.WithRenderDelay(delayCh))
p.Wait() // <-- Doesn't block, because no "alive" bars.
fmt.Println("Elapsed: ", time.Since(start))
}
Then this will finish without waiting for the render delay, as expected 👍.
The behavior should be the same if all of p
's bars are aborted/completed; p.Wait()
should not block (via render delay) on aborted/completed bars.
That is to say, it should be functionally equivalent to invoke p.Wait()
on an "empty" p
as invoking p.Wait()
on a p
with no "alive" bars.
from mpb.
bar.Wait
and p.Wait
is blocking for a reason. In order to remove completed/aborted bar at least one render cycle needs to be run. OnComplete/OnAbort
decorators demand at least two render cycle to be run. This is core design of this lib and I'm not going to change it.
from mpb.
@vbauerster Yes, I looked at the source code, and I understand your reluctance to address the issue. I think it would be a challenging fix.
I will document my understanding of the issue below, in case any other users encounter it.
Problem summary
mbp.WithRenderDelay
and mpb.BarRemoveOnComplete
interact to produce undesired behavior.
In the scenario I'm working with, some bars will complete before the render delay, and some will complete after the render delay. In both cases, the bar is to be removed. The expectation is that the short-lived bars are never rendered, because they were born and died before the render delay expired. This is not what happens.
Example
Take this example:
$ go install github.com/neilotoole/mpb-render-delay@example-six-seconds
$ mpb-render-delay
This causes a single-frame "flash" of the aborted (already-dead) bars at the point of the render-delay expiration, and then proceeds correctly.
I've pulled this out into a super-slowmo video (in reality, it's just a single frame):
mpb-render-delay-slowmo.mp4
Obviously this isn't the desired outcome.
Next steps
Per @vbauerster's comment above, the interaction between RenderDelay
, BarRemoveOnComplete
and early-completing bars wasn't anticipated in the rendering pipeline design, and it seems it would be challenging to fix.
However, the exhibited "flash" behavior isn't acceptable in my use case. I suspect I will address the issue by implementing the render delay in an outer layer of decorators (for Progress
and Bar
) that wraps the mpb library, and avoid using mpb.RenderDelay
entirely. The outer decorators will defer creation of the Progress
and Bar
until the render delay expires; during this time the Bar
-decorator will store the IncrBy
calls in a variable. When the render delay expires, any non-aborted Bar
will be instantiated, and the stored increment value will be played-back on the newly-instantiated Bar
.
It's ugly, but it'll probably work. If I do manage to make it work, I'll follow up with a link to it here, for any other users who encounter the issue.
@vbauerster, thank you for taking the time to look at this issue. If you do ever create a v9 or revisit the rendering pipeline, maybe this scenario can be handled? Thanks again for a great library.
from mpb.
Thanks for detailed example, it helped me to apply I believe correct fix, at least "flash" behavior is gone when I tested it.
Hope it is acceptable fix for you.
from mpb.
@vbauerster I can confirm that the "flash" seen in the example is fixed on master
. Thank you. In the coming days I will incorporate master
into my main project (which has substantially more complex behavior) and verify that there's no other hidden gremlins, and then I'll close the ticket.
Keep up the great work, and thanks for being so responsive. It's a wonderful project.
from mpb.
@vbauerster In my (limited) testing, I haven't found any issues with the fix. Closing 👍
from mpb.
Related Issues (20)
- [bytes counter] when use EwmaSpeed ,speed and remain time calculate is wrong? HOT 4
- [QUESTION] Bar doesn't display right info.
- Bug: Bars are not completely removed HOT 3
- Leading white space not removable? HOT 2
- DynTotal with EWMA question HOT 1
- Adding color to one bar on abort adds colors to others in barExtenderRev example HOT 1
- Cannot show up progress bar at Goland terminal console HOT 1
- Ineffective breaks in heap_manager.go HOT 3
- Using Frogbot to scan this repository
- WithWaitGroup hangs on error. Help explain how to use WithWaitGroup. HOT 3
- SetTotal not working with complex bar HOT 1
- Progress.Wait() exits without waiting for Progress.Write() to complete HOT 7
- Invalid rate calculation HOT 2
- animated console SVGs in README HOT 1
- fatal error: unknown caller pc HOT 1
- Bar dupes when adding new bar HOT 1
- decor.OnAbortMeta bug
- progressAsWriter with logrus does not work HOT 2
- Progress Time Continues Increasing After Calling Abort(false) HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mpb.