[Bug] Console log fills up with empty lines if Multi-bar has more than 15 objects
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.
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
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.

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 ?
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.
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
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.
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
}
}
}
}
}
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
But I ran into another problem, my output breaks down - sometimes it does not specify parameters (or does not have time to update)
At the same time, the data from the Formatter is working correctly.

Getting the same issue when creating a multi bar with about 30 single bars.
Same issue when creating multibar witth about 50 bars.

Same issue here
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.