cli-progress icon indicating copy to clipboard operation
cli-progress copied to clipboard

[Bug] Console log fills up with empty lines if Multi-bar has more than 15 objects

Open RozenbergsR opened this issue 5 years ago • 12 comments

I create a multi-bar and create continuously create new bars to it, during which some of the bars have already finished. After I have added approximately 15 bars, when a new bar is added, it appears that the previous bars are replaced by empty lines and then the whole console log is filled with empty lines and now and then a bar pops up.

RozenbergsR avatar Jan 17 '20 15:01 RozenbergsR

HI @Japaanis ,

within the development environment the following snippet is running without any errors. please post a minimal example howto reproduce the error

const multibar = new _progress.MultiBar({
    clearOnComplete: false,
    hideCursor: true,
    format: ' processing.. {bar} | {percentage}% of {total}',
    stopOnComplete: true
}, _progress.Presets.rect);

console.log("adding bars..");
const bars = [];
for (let i=0; i<30; i++){
    bars.push(multibar.create(Math.floor(Math.random()*200), Math.floor(Math.random()*20)));
}

const timer = setInterval(function(){

    // increment bars
    bars.map(bar => bar.increment());
}, 10);

multibar.on('stop', () => {
    console.log("FINISHED");
    clearInterval(timer);
});

$ bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)

 $ node --version
v12.14.1

AndiDittrich avatar Jan 17 '20 19:01 AndiDittrich

I am also receiving the same behaviour.

I basically create a couple of progress bars, as they complete, more gets added (This is a type of http throttling call). After a while, there is a lot of space created between the bars and things look glitchy.

This is on a mac terminal.

image

aavanzyl avatar Jan 23 '20 13:01 aavanzyl

currently i'm unable to reproduce this behaviour - can you please provide a minimal example ? do you have any console messages or other stuff which is written to stdout/stderr ?

AndiDittrich avatar Jan 23 '20 13:01 AndiDittrich

Hi @AndiDittrich I tried running the example above, this produced the same results of spaces being added in between. So in terms of extra example or code, this should be able to produce the issue.

I have noticed that it happens easier the smaller your terminal window is, if my terminal is able to show everything, then it does not happen, but as soon as its sized a bit smaller than the content in height, it freaks out.

Here is some more info: I am running: MacOs Catalina 10.15.2 (19C57) Node: v10.16.3 NPM: v6.13.1 cli-progress: 3.5.0

Is there more I can do to help, let me know.

aavanzyl avatar Jan 23 '20 15:01 aavanzyl

thanks for the window size hint.

generally the window should be bigger than the bar....otherwise it can cause an undefined behaviour. the options forceRedraw: true will solve the issue with empty lines but the stream will be still messed up with the bar output


the issue is caused be the relative cursor movement within the window - i'm not sure if it is possible to fix this without a virtual framebuffer - but due to possible performance impacts i would avoid to implement it

AndiDittrich avatar Jan 23 '20 19:01 AndiDittrich

I also see the same issue (using Windows 10 Command Prompt) when the multiline output grows taller than the screen height, which @AndiDittrich already addressed.

Here's a workaround that worked for my situation. I am running 100's of child processes 25 at a time, so I have a 'total' bar followed by 25 'child' bars, removing completed bars and adding child bars as children complete.

Call <instance>.remove(<barInstance>:object) after the progress line is complete. You will still run into the issue if you exceed your screen height, but this helps a lot. Using the forceRedraw: true option improves it even further.

This is cleaner for me. However, I imagine one could use the <barInstance> methods and options to reuse the line, instead of re-creating it. Though I didn't try it.

wwwebbify avatar Jul 21 '20 16:07 wwwebbify

Also running into this when creating dozens or hundreds of bars and I didn't want to manage which bars to show manually.

I made a hacky fix by kicking out old completed items by extending the class. This could potentially be incorporated as a bug fix with an option for the max bars to render simultaneously with undefined/0 meaning don't perform cleanup.

My use case generally only has 8 active jobs at a time so I picked 20 arbitrarily since it usually fits and I want to see the recently completed jobs. I decided to move failed reports into a file to keep the visibility lost by dropping inactive bars like this.

class FixedMultiBar extends MultiBar {
  create(total: number, startValue: number, payload?: any): SingleBar {
    this.cleanup()
    return super.create(total, startValue, payload)
  }

  private cleanup() {
    // @ts-ignore - internal API. Keep in sync with code when updating
    const bars = this.bars
    if (bars.length > 20) {
      // clear the initial completed items up to current total - 20
      for (let i = 0, to = bars.length - 20; i < to; i++) {
        const inst = bars[i]
        // @ts-ignore - internal API. Keep in sync with code when updating
        if (!inst.isActive) {
          this.remove(inst!)
        } else {
          break
        }
      }
    }
  }
}

meticoeus avatar May 22 '21 00:05 meticoeus

Faced a similar problem, but as I understood my mistake was that I did not delete the expired instances of the progress bar, or I used more than the command line window Now I am clearing the used progress bars and using only 4 at a time image But I ran into another problem, my output breaks down - sometimes it does not specify parameters (or does not have time to update) image image image image At the same time, the data from the Formatter is working correctly. image

JoCat avatar Sep 11 '21 20:09 JoCat

Getting the same issue when creating a multi bar with about 30 single bars.

Screenshot 2022-07-18 at 10 44 36

paul-uz avatar Jul 18 '22 09:07 paul-uz

Same issue when creating multibar witth about 50 bars. 2022-07-23_23-36

abhinavdhakal avatar Jul 23 '22 17:07 abhinavdhakal

Same issue here

tschirmer avatar Nov 14 '22 01:11 tschirmer

Also running into this when creating dozens or hundreds of bars and I didn't want to manage which bars to show manually.

I made a hacky fix by kicking out old completed items by extending the class. This could potentially be incorporated as a bug fix with an option for the max bars to render simultaneously with undefined/0 meaning don't perform cleanup.

My use case generally only has 8 active jobs at a time so I picked 20 arbitrarily since it usually fits and I want to see the recently completed jobs. I decided to move failed reports into a file to keep the visibility lost by dropping inactive bars like this.

class FixedMultiBar extends MultiBar {
  create(total: number, startValue: number, payload?: any): SingleBar {
    this.cleanup()
    return super.create(total, startValue, payload)
  }

  private cleanup() {
    // @ts-ignore - internal API. Keep in sync with code when updating
    const bars = this.bars
    if (bars.length > 20) {
      // clear the initial completed items up to current total - 20
      for (let i = 0, to = bars.length - 20; i < to; i++) {
        const inst = bars[i]
        // @ts-ignore - internal API. Keep in sync with code when updating
        if (!inst.isActive) {
          this.remove(inst!)
        } else {
          break
        }
      }
    }
  }
}

This worked good enough for me. only issue to point out is that the constructor lacks the option field passed to the super class.

artistXenon avatar Dec 26 '22 03:12 artistXenon