vbauerster / mpb Goto Github PK
View Code? Open in Web Editor NEWmulti progress bar for Go cli applications
License: The Unlicense
multi progress bar for Go cli applications
License: The Unlicense
When BarClearOnComplete option is set, bar section clears too early, before 100 %.
It is obvious, for example when number of bars set to 8, here.
With my library that I primarily to use to make web scrapers, there are two main types of bars. those being manual value ones and download ones. and as the byte formatting makes the counter column much wider than normal as shown below.
however, as many downloads may appear and disappear but a parent bar, this width difference can cause it to be very spam-y and make that column hard to read.
therefore I was hoping it would be possible to be able to tell mpb that the width of that column should be remembered shortly (perhaps 1s) before shrinking. currently I use decor.WCSyncWidth
.
Is there a way to clear the spinner after complete? Like the one for bar using mpb.BarClearOnComplete()
Hello,
Is it possible to prevent a bar from completing until the final total is set?
My problem is the code to determine size is slower than the code to process items so the bar completes before I have a chance to set the final total.
In the interim I have worked around by artificially adding an extra item to the total at the start and then subtracting this at the end.
Cheers
Seth
Apply the following diff:
diff --git a/examples/remove/main.go b/examples/remove/main.go
index 8abfaea..a727bc2 100644
--- a/examples/remove/main.go
+++ b/examples/remove/main.go
@@ -39,13 +39,10 @@ func main() {
defer wg.Done()
max := 200 * time.Millisecond
for i := 0; i < total; i++ {
- if b.ID() == 1 && i == 42 {
- p.RemoveBar(b)
- return
- }
- time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
+ time.Sleep(time.Duration(rand.Intn(10)+1) * max / 100)
b.Increment()
}
+ p.RemoveBar(b)
}()
}
Then run examples/remove/main.go repeatedly. Note sometimes some bars are removed, but in general the output is very inconsistent.
I tried debugging the r.toRemove part in the writeAndFlush function, it seems to never be called at all.
I'm not familiar enough with this code to efficiently debug it further myself. My guess is bars that are completed don't get updated anymore, hence they don't get removed.
The ETA isn't working correctly. It's initially non-zero, but drops to zero and stays there for most of the duration. I have a wrapper around theio.Reader
that iteratively provides counts and durations. The durations are in the microsecond range.
The documentation for the timing arguments is very terse and, simple person that I am, the examples don't expand the understanding in any way that'd help to debug. I'd appreciate some assistance.
Implementation (based on the example):
progress := mpb.New()
bar := progress.AddBar(
fi.Size(),
mpb.PrependDecorators(
// display our name with one space on the right
decor.Name(
currentFilepath,
decor.WC{W: len(currentFilepath) + 1, C: decor.DidentRight}),
// replace ETA decorator with "done" message, OnComplete event
decor.OnComplete(
// ETA decorator with ewma age of 60, and width reservation of 4
decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WC{W: 4}), "done",
),
),
mpb.AppendDecorators(decor.Percentage()),
)
progressCb = func(n int, duration time.Duration, isEof bool) error {
bar.IncrBy(n, duration)
return nil
}
I'm trying to understand how the ETA is supposed to work, but it's not clear, at least to me, from the documentation.
Output:
$ time go run cmd/gozp/main.go -f /tmp/big.gzp file.mp4
file.mp4 0s [==============================================>-------------------------------] 60 %
^Csignal: interrupt
real 0m12.364s
user 0m12.862s
sys 0m0.356s
This has at least another ten or twenty seconds to go at the 60% mark, but it dropped to (0) right after starting.
Right now there is no way to update the bar title or any decorator text, only change their configs.
Additionally, decor.CBFunc
takes no index, so you have no idea which decorating with Bar.TraverseDecorators.
Hi,
first off, thanks for this great library. I am quite excited about it!
I am working on porting our tools to use it (see containers/image#581) but I am currently stuck with the below issue.
We need to vendor the code and use github.com/LK4D4/vndr
for managing the dependencies. So far I tried vendoring github.com/vbauerster/mpb directly and also doing dance with gopkg.in/vbauerster/mpb.v4/ as shown in the error below. None of it succeeded.
Can you shed some light on my issue?
vendor/gopkg.in/vbauerster/mpb.v4/progress.go:13:2: cannot find package "github.com/vbauerster/mpb/v4/cwriter" in any of:
/home/valentin/go/src/github.com/containers/skopeo/vendor/github.com/vbauerster/mpb/v4/cwriter (vendor tree)
/usr/lib/golang/src/github.com/vbauerster/mpb/v4/cwriter (from $GOROOT)
/home/valentin/go/src/github.com/vbauerster/mpb/v4/cwriter (from $GOPATH)
vendor/gopkg.in/vbauerster/mpb.v4/bar.go:14:2: cannot find package "github.com/vbauerster/mpb/v4/decor" in any of:
/home/valentin/go/src/github.com/containers/skopeo/vendor/github.com/vbauerster/mpb/v4/decor (vendor tree)
/usr/lib/golang/src/github.com/vbauerster/mpb/v4/decor (from $GOROOT)
/home/valentin/go/src/github.com/vbauerster/mpb/v4/decor (from $GOPATH)
vendor/gopkg.in/vbauerster/mpb.v4/bar_filler.go:9:2: cannot find package "github.com/vbauerster/mpb/v4/internal" in any of:
/home/valentin/go/src/github.com/containers/skopeo/vendor/github.com/vbauerster/mpb/v4/internal (vendor tree)
/usr/lib/golang/src/github.com/vbauerster/mpb/v4/internal (from $GOROOT)
/home/valentin/go/src/github.com/vbauerster/mpb/v4/internal (from $GOPATH)
First of all, many thanks for your work!
I have a question: How can I dynamic setting the total value of bar?
Thanks!
how close progress bar (stop rendering) without close whole program ?
Running the IO example given here https://github.com/vbauerster/mpb/blob/master/_examples/io/main.go with some modifications to prepend a long name, I have reproduced an issue I'm having where bars get duplicated once they reach the edge of the terminal window.
package main
import (
"crypto/rand"
"io"
"io/ioutil"
"time"
"github.com/vbauerster/mpb/v5"
"github.com/vbauerster/mpb/v5/decor"
)
func main() {
var total int64 = 1024 * 1024 * 1024
reader := io.LimitReader(rand.Reader, total)
p := mpb.New(
mpb.WithWidth(60),
mpb.WithRefreshRate(180*time.Millisecond),
)
bar := p.AddBar(total, mpb.BarStyle("[=>-|"),
mpb.PrependDecorators(
decor.Name("This is a really long name. I'm sorry it's so long but that's just the way it goes sometimes. "),
decor.CountersKibiByte("% .2f / % .2f"),
decor.Percentage(decor.WCSyncSpace),
),
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_GO, 90),
decor.Name(" ] "),
decor.EwmaSpeed(decor.UnitKiB, "% .2f", 60),
),
)
// create proxy reader
proxyReader := bar.ProxyReader(reader)
defer proxyReader.Close()
// copy from proxyReader, ignoring errors
io.Copy(ioutil.Discard, proxyReader)
p.Wait()
}
The bar is clearly flexing to fill available space, but is still one character too long, it seems. Shorter names do not produce this issue.
OS: Windows 10
Hi, I'm trying to using SetTotal
after progress done before to ensure the progress state.
However, it stops at SetTotal
:
Here is the code:
package main
import (
"fmt"
"time"
"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)
func main() {
index := "index"
p := mpb.New(mpb.WithRefreshRate(time.Second))
bar := p.AddBar(0,
// mpb.BarRemoveOnComplete(),
mpb.PrependDecorators(
// simple name decorator
decor.Name(index),
// decor.DSyncWidth bit enables column width synchronization
decor.Percentage(decor.WCSyncSpace),
),
mpb.AppendDecorators(
// replace ETA decorator with "done" message, OnComplete event
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
)
bar.SetTotal(2, false)
time.Sleep(2 * time.Second)
bar.Increment()
fmt.Printf("incr1\n")
time.Sleep(2 * time.Second)
bar.Increment()
fmt.Printf("incr2\n")
time.Sleep(2 * time.Second)
fmt.Printf("incr3\n")
bar.Increment()
fmt.Printf("incr4\n")
bar.SetTotal(2, true)
fmt.Printf("setTotal\n")
fmt.Printf("done\n")
}
it will never print setTotal
and stop at bar.SetTotal(2, true)
.
This is a feature request.
Is it possible to have an IncrBy that takes in64 as input please?
I'm working with file sizes and the ProxyReader doesn't work for me as I want to also do an ETA based on bytes processed.
Thanks
Although I've used BarRemoveOnComplete
on AddBar
, I am making sure SetTotal
and SetCurrent
are correctly set to be completed, and I'm waiting for Wait
to complete, sometimes the bar fails to be removed after completion.
Through experimentation, I've observed that waiting after Wait
the same amount of time (plus some extra) as I've set with mpb.WithRefreshRate
, seems to solve the issue.
This makes me think there is perhaps a race condition happening inside Wait
?
Hi again! ๐
A few questions if I may:
decor.Name("name\n")
, but that gets the first line duplicated.p.Add()
with a filler that prints a string as the 2nd argument, and ampb.BarExtender()
with a bar as filler as a BarOption. Both lines are duplicated.Thanks a lot in advance!
Currently, mpb
's implementation imports from github. Thus if you exec go get gopkg.in/vbauerster/mpb.v3
you actually fetch the project twice. Besides, the second copy from github is not synced with v3 release, and the project may become unusable.
Another side effect is that if you import mpb
like that:
import (
"gopkg.in/vbauerster/mpb.v3"
"gopkg.in/vbauerster/mpb.v3/decor"
)
The build fails because "gopkg.in/vbauerster/mpb.v3"
imports "github.com/vbauerster/mpb/decor"
and the types from decor
do not match:
cannot use "gopkg.in/vbauerster/mpb.v3/decor".DynamicName(func literal, 10, 0) (type "gopkg.in/vbauerster/mpb.v3/decor".DecoratorFunc) as type "github.com/vbauerster/mpb/decor".DecoratorFunc in argument to mpb.PrependDecorators
So to actually build the examples, we need
import (
"gopkg.in/vbauerster/mpb.v3"
"github.com/vbauerster/mpb/decor"
)
which does not make any sense to me. So I propose to rediect the internal imports to gopkg.in
, as the rest of the folks do.
Hi. How do I reset the bar and restart after it's completed?
I'm honestly not sure how it's crashing here..
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x4d07c7]
goroutine 1 [running]:
github.com/vbauerster/mpb.(*Bar).SetTotal(0x0, 0x19cb8, 0x4aa600)
/home/meghan/go/src/github.com/vbauerster/mpb/bar.go:214 +0x37```
mpb panics when multiple bars have different number of prependers / appenders.
from progress_posix.go
b0 := s.bars[0]
if numP == -1 {
numP = b0.NumOfPrependers()
}
This assumes all bars use the same number of prependers / appenders.
It can be fixed in a naive (slow) way that calculates the maxmium number of columns every tick:
// if(numP==-1) <-- numP can be changed if you add/remove a bar.
for _, bar := range s.bars {
num := bar.NumOfPrependers()
if num > numP {
numP = num
}
}
My goroutines dynamically create/remove bars, and their order on the screen depend on the order of execution (which is random). Is it possible to give a specific order between bars?
If not, can we add something like p.AddBar(priority=int)
, or to prevent a frequent move, p.AddBar(absolute_row=int)
.
Take the following example code:
package main
/* This example creates three bars: b1, b2, and b3.
* b1 is created in the main thread but runs in a separate thread.
* b2 is created in b1's thread, but runs in its own thread.
* b3 is created and run in its own thread.
* b1 and b3 appear immediately, but b2 comes later.
* b2 is the fastest and should complete and be removed first.
* b1 is second fastest and should complete and be removed second.
* b3 is the slowest and should complete last.
*/
import (
"time"
"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)
const sleep = 100 * time.Millisecond
func main() {
p := mpb.New()
b1 := p.AddBar(int64(100), mpb.PrependDecorators(decor.StaticName("bar1", 0, 0)))
// Run thread for b1.
go func() {
defer p.RemoveBar(b1)
// Create and run thread for b2, which starts after a time.
go func() {
time.Sleep(10 * sleep)
b2 := p.AddBar(int64(100), mpb.PrependDecorators(decor.StaticName("bar2", 0, 0)))
defer p.RemoveBar(b2)
for j := 0; !b2.Completed(); j++ {
b2.IncrBy(10) // fastest
time.Sleep(sleep)
}
}()
for i := 0; !b1.Completed(); i++ {
b1.IncrBy(2) // second fastest
time.Sleep(sleep)
}
}()
// Create and run thread for b3, which starts immediately.
go func() {
b3 := p.AddBar(int64(100), mpb.PrependDecorators(decor.StaticName("bar3", 0, 0)))
defer p.RemoveBar(b3)
for k := 0; !b3.Completed(); k++ {
b3.IncrBy(1) // slowest
time.Sleep(sleep)
}
}()
p.Wait()
}
None of the bars will end up being removed.
I am implementing a progress bar using your great repo, but I got stuck on the following situation. The speed field and left time field remains zero while the program is running, could you please help me to figure out where I am wrong? Thank you so much!
package main
import (
"time"
"github.com/vbauerster/mpb/v5"
"github.com/vbauerster/mpb/v5/decor"
)
func main() {
var totalBytes int64 = 1024
p := mpb.New(
mpb.WithWidth(60),
mpb.WithRefreshRate(180*time.Millisecond),
)
bar := p.AddBar(totalBytes, mpb.BarStyle("[=>-|"),
mpb.PrependDecorators(
decor.CountersKibiByte("% .2f / % .2f"),
),
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_GO, 90),
decor.Name(" ] "),
decor.EwmaSpeed(decor.UnitKiB, "% .2f", 60),
),
)
for i := 0; i < 1024; i++ {
bar.Increment()
time.Sleep(1 * time.Second)
}
p.Wait()
}
4.00 b / 1.00 KiB [----------------------------------------------------------| 0s ] 0.00 b/s
4.00 b / 1.00 KiB [----------------------------------------------------------| 1020s ] 1.00 b/s
When using the ProxyReader with empty files, progress bars never complete and end up locking up the program on exit. This also seems to happen with empty normal progress bars
Task 47 : 1881 / 1885 [================================] 100 %: 00:06:
This is in reference to the 1881 / 1885
which is calculated with using
decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
Hi,
We're investigating a weird content corruption in our S3-compatible CLI tool, which is using the minio/minio-go/v6 and mpb/v4 packages. We've opened an issue at minio-go to discuss the problem, and while performing tests we've found out that the content corruption is directly linked to the progress bar usage. Could you please have a look at this and point to us to a potential misuse of your package in our code? That'd be great to help ruling out possibilities :)
The method signature has age but the comment has average function
func EwmaSpeed
func EwmaSpeed(unit int, unitFormat string, age float64, wcc ...WC) Decorator
`unit` one of [0|UnitKiB|UnitKB] zero for no unit
`unitFormat` printf compatible verb for value, like "%f" or "%d"
`average` MovingAverage implementation
`wcc` optional WC config
Unlicense is a type of Public Domain attribution that has significant legal issues due to local rules about Public Domain status, and may actually make it difficult for people to use or contribute.
Looking back at the history of this project, it actually was BSD-3-Clause before, which does not have these legal issues. Frankly that's a major step back. Going to BSD-2-Clause would have been better, MIT/ISC too.
I would strongly urge you to pick a real code license and not a PD attribution-like license. MIT/BSD's are all fine, Apache-2.0 would be fine, but Unlicense and other PD attributions should be avoided.
Disclaimer: IANAL
Hello,
Do you have an example where I can have a scrolling output above a progress bar? I don't need it above each individual bar just above the progress.
Cheers
Seth
How do I set the starting point for use with resumed downloads?
p := mpb.New(
mpb.WithWidth(60),
mpb.WithRefreshRate(180*time.Millisecond),
)
bar := p.AddBar(d.size, mpb.BarStyle("[=>-|"),
mpb.PrependDecorators(
decor.CountersKibiByte("\t% 6.1f / % 6.1f"),
),
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_MMSS, float64(d.size)/2048),
decor.Name(" ] "),
decor.AverageSpeed(decor.UnitKiB, "% .2f"),
),
)
if d.canResume {
bar.SetCurrent(d.bytesResumed )
}
// create proxy reader
reader := bar.ProxyReader(resp.Body)
defer reader.Close()
โข resuming a previous download of: iPhone12_1_13.1.1_17A854_Restore.ipsw
1.1 GiB / 0 b [----------------------------------------------------------| -48:-3 ] 71.44 MiB/s
See the total byte sits at 0b and the estimated time is negative??
Thank you!
The increment only or relative interface feels a little awkward for some use cases. Is there a particular reason not to allow for setting the absolute value of the progress?
I must be doing something wrong, I'm hoping someone can spot it easily and help me out.
https://asciinema.org/a/emiUqPl3r9mIrj9CudPv0fJa3
The data below the bar is what I was calculating myself before finding this neat progress bar, but the eta on the bar seems to be going the wrong way fast?
code:
https://gist.github.com/sedlund/dd27e52a21b443713eb7ece80d35d3d4
When I "go get" this package, I get this complaint:
package context: unrecognized import path "context" (import path does not begin with hostname)
I am guessing this must be due to progress.go
and bar.go
importing context
while there is no context.go
.
I want to calculate the elapsed time of each progress bar, and output the time on
AppendDecorators. But the time of finished bar keep growing, even when the progress of this bar is finished. Thus, the final elapsed time is always the same.
BTW, is it possible to write a progress bar group that dropout each bar when it is finished. But keep the final completed one.
When 4 bars where updated with nearly 8 goroutines each, cpu usage have raised from 20% to 75%,.
After removing progress bar, same computation took less than 25% cpu usage.
This issue has popped up due to the fact that the way I use mpb I don't always know the exact titles that are going to be on all the bars I use, namely URLs. This leads to a situation where the line overflows and then the erase/redraw isn't clean and repeats a bunch of lines until the bar is finished/removed.
So being able to set a particular decorator as 'able to be cropped' would be very handy.
(If you're unsure of what I'm referring to I can try and reproduce and at screenshots at a later time.)
A non zero init value will be really helpful, As it would make the average speed and eta more accurate for resume able task. Hope I can convey my thoughts clearly.
Is there any possibility of having a call-back function being called before refreshing bars, If so how?
i.e.,
bar.BeforeRefresh(func(){})
If this is not possible, can you provide it?
Why do I need it?
I use aria2c for downloading, I'm trying to get status of from aria2c
, only before refreshing, so I can save some CPU time.
Thank you.
Take the following sample code:
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strconv"
"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)
func main() {
workers := 3
tiny := "https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"
urls := []string{tiny, tiny, tiny, tiny, tiny, tiny, "http://ipv4.download.thinkbroadband.com/512MB.zip"}
jobs := make(chan string, len(urls))
done := make(chan bool, workers)
p := mpb.New(mpb.WithWidth(64))
for w := 1; w <= workers; w++ {
go func(jobs <-chan string) {
for entry := range jobs {
download(entry, p)
}
done <- true
}(jobs)
}
for _, url := range urls {
jobs <- url
}
close(jobs)
for w := 1; w <= workers; w++ {
<-done
}
p.Wait()
fmt.Println("done")
}
func download(url string, p *mpb.Progress) {
resp, err := http.Head(url)
if err != nil {
panic(err)
}
size, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
resp, err = http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Server return non-200 status: %s\n", resp.Status)
return
}
// create dest
destName := filepath.Base(url)
dest, err := os.Create(destName)
if err != nil {
fmt.Printf("Can't create %s: %v\n", destName, err)
return
}
defer dest.Close()
bar := p.AddBar(int64(size),
mpb.BarRemoveOnComplete(),
mpb.PrependDecorators(
decor.CountersKibiByte("% 6.1f / % 6.1f", 18, 0)),
mpb.AppendDecorators(decor.ETA(0, decor.DwidthSync)))
// create proxy reader
reader := bar.ProxyReader(resp.Body)
// and copy from reader, ignoring errors
io.Copy(dest, reader)
}
Note that this is using 3 channel workers, so only 3 downloads occur at a time. A new worker (and thus progressbar) isnt created until an old one has completed.
When you run the code you briefly see all progressbars spawned and then see the expired ones disappear soon after. It seems it is prioritising creating new progressbars over destroying old ones, making it so your screen gets filled with stale progressbars and creating a glitchy user experience.
Use the following sample code:
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"sync"
"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)
func main() {
var wg sync.WaitGroup
wg.Add(3)
p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(64))
go download(p, &wg)
go download(p, &wg)
go download(p, &wg)
wg.Wait()
p.Wait() // if you omit this line, rendering bars goroutine will quit early
fmt.Println("done")
}
func download(p *mpb.Progress, wg *sync.WaitGroup) {
defer wg.Done()
url := "http://ipv4.download.thinkbroadband.com/512MB.zip"
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Server return non-200 status: %s\n", resp.Status)
return
}
size := resp.ContentLength
// create dest
destName := filepath.Base(url)
dest, err := os.Create(destName)
if err != nil {
fmt.Printf("Can't create %s: %v\n", destName, err)
return
}
defer dest.Close()
bar := p.AddBar(size,
mpb.PrependDecorators(
decor.CountersKibiByte("% 6.1f / % 6.1f", 18, 0)),
mpb.AppendDecorators(decor.ETA(0, decor.DwidthSync)))
// create proxy reader
reader := bar.ProxyReader(resp.Body)
// and copy from reader, ignoring errors
io.Copy(dest, reader)
fmt.Printf("Downloaded")
}
Note the ETA's on the downloads are jumping up and down all over the place, they do not settle down as time goes on. In my actual use-case they actually run down to 0 in the first 50% and then remain there, I'm not sure how to get that to reproduce though.
Hi,
we're currently using v3.3.4 as we're not (yet) using Go mod. Is there a way to create a new bar that doesn't display a progress bar?
What we're trying to achieve is first print some kind of "placeholder" bar that is later being replaced with another bar if needed. Imagine it as follows:
Bar 1: waiting for something to happen
Bar 2: performing work [=======> ]
At a later point, we want to replace Bar 1
with something similar to Bar 2
.
I haven't seen an obvious way to do this with mpb, but I'd love to be able to print line-based output ("Downloaded file a\nDownloaded file b\n" etc) while also having a progress bar.
Ideally this would be presented as an io.Writer so I can plug it into existing code that is expecting to just write non-atomically directly to stdout.
The io.Copy
function has optimizations where the Reader implements io.ReadFrom
.
// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
....
For example sftp.File
implements io.ReadFrom
. So if you attempt to download a file from sftp
and wrap it with a mpb.proxyReader
then io.Copy
is unable to use the io.ReaderFrom
optimization.
I was thinking about migrating from https://github.com/cheggaaa/pb to mpb since it has multiple progress bar support and noticed that mpb just proxies a reader. Would it be of interest to do a writer proxy as well?
Hi,
Thanks for your library and all your work!
Im running mpb v4.6.0 on macOS.
I tried running the stress example and it seems that when the number of lines displayed in the terminal (a matter of font & window size) is lower than the number of bars, the first bars get duplicated.
For example, when running the example with the default 32 bars, while terminal displays less than 30 lines:
last lines printed:
first lines printed:
Please correct me if I'm doing something wrong, or it is a known limitation I'm unaware of.
Thanks!
The following code represents my progress bar
p.AddBar(fileInfo.Size(),
mpb.PrependDecorators(
// simple name decorator
decor.Name(task.string),
// decor.DSyncWidth bit enables column width synchronization
decor.Percentage(decor.WCSyncSpace),
),
mpb.AppendDecorators(
// replace ETA decorator with "done" message, OnComplete event
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
)
this is the output during progress:
an example 4 % [=>------------------------------------------------------------] 0s
then when it is done
an example 100 % [=============================================] done
Why during the progress ETA is displayed and why is doesn't working ?
if I remove this part of code:
mpb.AppendDecorators(
// replace ETA decorator with "done" message, OnComplete event
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
It's works good, but done
message at the end is not displayed naturally
Hello,
OBS. I am extremely new with Golang.
I'm looking for a solution to an idea, I want to improve the output of this program:
https://github.com/dgraph-io/dgraph/tree/master/dgraph/cmd/live
I seek for bars like mpb (sounds like brasilian music LOL) but that it can generate a clean output. All projects with bars generate many lines (per second). I'm using | & tee -a bartest.txt to test.
go run main.go |& tee -a bartest.txt
I wonder if it would be possible to combine the best of both worlds. Bar + a clean output.
The program also issues errors while continuing the process. It would be interesting to display the errors while the progress bar maintains its rhythm. And the output also collects the errors.
At the end of the process if is either fatal error, cancellation, SIGTERM or something else. The program still generates a clean output of what happened.
All this Would it be possible?
This would be an example of the current output
2018/07/29 22:31:59 run.go:337: Creating temp client directory at /var/folders/vb/l72zg91129q5wyqygw59cr2h0000gn/T/x236306353
Processing 21million.schema
2018/07/29 22:32:00 run.go:354: Processed schema file
Processing 1million.rdf.gz
Total Txns done: 0 RDFs per second: 0 Time Elapsed: 2s, Aborts: 0
Total Txns done: 0 RDFs per second: 0 Time Elapsed: 4s, Aborts: 0
Total Txns done: 0 RDFs per second: 0 Time Elapsed: 6s, Aborts: 0
Total Txns done: 0 RDFs per second: 0 Time Elapsed: 8s, Aborts: 0
Total Txns done: 323 RDFs per second: 1564 Time Elapsed: 3m26s, Aborts: 0
2018/07/29 22:35:27 batch.go:125: Error while mutating Predicate is being moved, please retry later
Total Txns done: 327 RDFs per second: 1568 Time Elapsed: 3m28s, Aborts: 1
2018/07/29 22:35:28 batch.go:125: Error while mutating Predicate is being moved, please retry later
2018/07/29 22:35:28 batch.go:125: Error while mutating Predicate is being moved, please retry later
2018/07/29 22:35:28 batch.go:125: Error while mutating Predicate is being moved, please retry later
It displays transactions, time and possible aborts.
Hi,
We are using mpb and would like have some spinners rather than progress bars. Do you see an easy way to inject a strategy for a custom s.fillBar(width)
?
I'm writing a downloader that shows bars as workers, a download can be hundreds of files so I want to have it reuse X number of bars. So either I need to reset a bar (feels dirty) or remove a bar when it's finished and add a new one.
Regardless of my use case, allowing for a bar to be removed seems like a basic functionality others would likely also benefit from.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.