Giter Club home page Giter Club logo

Comments (9)

vbauerster avatar vbauerster commented on June 21, 2024

Should be fixed. If you can test against latest master branch, please do. I didn't test your example thoroughly.

from mpb.

neilotoole avatar neilotoole commented on June 21, 2024

@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.

vbauerster avatar vbauerster commented on June 21, 2024

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.

neilotoole avatar neilotoole commented on June 21, 2024

@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.

vbauerster avatar vbauerster commented on June 21, 2024

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.

neilotoole avatar neilotoole commented on June 21, 2024

@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.

vbauerster avatar vbauerster commented on June 21, 2024

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.

neilotoole avatar neilotoole commented on June 21, 2024

@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.

neilotoole avatar neilotoole commented on June 21, 2024

@vbauerster In my (limited) testing, I haven't found any issues with the fix. Closing 👍

from mpb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.