cheggaaa / pb Goto Github PK
View Code? Open in Web Editor NEWConsole progress bar for Golang
License: BSD 3-Clause "New" or "Revised" License
Console progress bar for Golang
License: BSD 3-Clause "New" or "Revised" License
Hello, thanks for your work.
I want to print some log when the progress bar is running. But I run in to trouble.
What I want to achieve:
some log 0
some log 1
some log 2
some log 3
some log 4
some log 5
some log 6
some log 7
some log 8
some log 9
10 / 10 [=================================================] 100.00% 4s
The End!
I got this:
0 / 10 [-----------------------------------------------------] 0.00%some log 0
1 / 10 [====>---------------------------------------------] 10.00% 1ssome log 1
2 / 10 [=========>----------------------------------------] 20.00% 2ssome log 2
3 / 10 [==============>-----------------------------------] 30.00% 2ssome log 3
4 / 10 [===================>------------------------------] 40.00% 2ssome log 4
5 / 10 [========================>-------------------------] 50.00% 1ssome log 5
6 / 10 [=============================>--------------------] 60.00% 1ssome log 6
7 / 10 [==================================>---------------] 70.00% 1ssome log 7
8 / 10 [=======================================>----------] 80.00% 0ssome log 8
9 / 10 [============================================>-----] 90.00% 0ssome log 9
10 / 10 [=================================================] 100.00% 4s
The End!
my code:
package main
import (
"gopkg.in/cheggaaa/pb.v1"
"time"
"fmt"
)
func main() {
count := 10
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
fmt.Println("some log", i)
bar.Increment()
time.Sleep(400 * time.Millisecond)
}
bar.FinishPrint("The End!")
}
have tested on Ubuntu 14.04
with zsh 5.0.2
is there any direction I can look for?
Thanks in advance!
when the text is too long and wrap, it didn't seem to update the previous line correctly and reprint the previous line multiple times.
go version go1.7.4 darwin/amd64
macos 10.12.1
use readme code
package main
import (
"math/rand"
"sync"
"time"
"gopkg.in/cheggaaa/pb.v1"
)
func main() {
// create bars
first := pb.New(200).Prefix("First ")
second := pb.New(200).Prefix("Second ")
third := pb.New(200).Prefix("Third ")
// start pool
pool, err := pb.StartPool(first, second, third)
if err != nil {
panic(err)
}
// update bars
wg := new(sync.WaitGroup)
for _, bar := range []*pb.ProgressBar{first, second, third} {
wg.Add(1)
go func(cb *pb.ProgressBar) {
for n := 0; n < 200; n++ {
cb.Increment()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
}
cb.Finish()
wg.Done()
}(bar)
}
wg.Wait()
// close pool
pool.Stop()
}
Looks like if you disable ShowCounters it still flickers, then moves the progress bar to the left, the bar itself seems to change sizes a bit too.
The other thing that might be nice is if Close()
clears the line by default, so you can use it as a direct reader proxy without exposing the progress bar at all.
Awesome pkg thanks!
The config I'm using is
// Proxy reader with a progress bar.
func Proxy(size int, r io.ReadCloser) io.ReadCloser {
bar := pb.New(size)
bar.SetMaxWidth(80)
bar.Start()
// bar.ShowCounters = false
bar.ShowTimeLeft = false
bar.SetUnits(pb.U_BYTES)
bar.Format("[▉▉ ]")
bar.SetRefreshRate(50 * time.Millisecond)
return bar.NewProxyReader(r)
}
Building ProgressBar on windows fails as pb_win.go includes github.com/olekukonko/ts which doesn't seem to exist.
A private not public repo?
Now that you tagged a first v1 version (#73), could you use versioned URLs for the import path? This allows you to make a breaking change and increase the major version, without affecting users of the previous major version. All that is needed is the following substitution in README
and *_test.go
:
github.com/cheggaaa/pb
→ gopkg.in/cheggaaa/pb.v1
It would be great if you could release v1.0.1 including this change.
I can't seem to get example/copy/copy.go
to work, it appears the code is broken.
This line sometimes ends up negative (not sure why), which then causes setCursorPos to return an error and this lib to panic.
The quick fix I did for myself was just to check if Y < 0 and set it Y = 0 (which seems to work), but you may want a better fix.
$ GOOS=windows GOARCH=amd64 go get
# github.com/cheggaaa/pb
../../../cheggaaa/pb/pb_nix.go:7: undefined: syscall.SYS_IOCTL
../../../cheggaaa/pb/pb_x.go:16: bold redeclared in this block
previous declaration at ../../../cheggaaa/pb/pb_win.go:9
../../../cheggaaa/pb/pb_x.go:20: terminalWidth redeclared in this block
previous declaration at ../../../cheggaaa/pb/pb_win.go:13
../../../cheggaaa/pb/pb_x.go:22: undefined: syscall.TIOCGWINSZ
../../../cheggaaa/pb/pb_x.go:30: not enough arguments in call to syscall.Syscall
Looks like your Pool.print implementation reads Pool.bars, which gets written to whenever you call Pool.Add.
You should probably synchronize operations on the bars slice in the pool.
==================
WARNING: DATA RACE
Write at 0x00c04204da40 by goroutine 22:
sync/atomic.AddInt64()
C:/Go/src/runtime/race_amd64.s:276 +0xb
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Add64()
D:/Dropbox/Go/src/gopkg.in/cheggaaa/pb.v1/pb.go:156 +0x4b
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Add()
D:/Dropbox/Go/src/gopkg.in/cheggaaa/pb.v1/pb.go:152 +0x49
main.(*pbReporter).Write()
D:/Dropbox/Go/src/github.com/djherbis/watch/progress.go:27 +0x5d
io.(*multiWriter).Write()
C:/Go/src/io/multi.go:51 +0xb5
io.copyBuffer()
C:/Go/src/io/io.go:392 +0x1d8
io.Copy()
C:/Go/src/io/io.go:360 +0x85
main.download()
D:/Dropbox/Go/src/github.com/djherbis/watch/download.go:43 +0x32b
main.remoteFile.Download()
D:/Dropbox/Go/src/github.com/djherbis/watch/crawl.go:40 +0x5d
main.downloadFiles.func1()
D:/Dropbox/Go/src/github.com/djherbis/watch/crawl.go:46 +0x5d
Previous read at 0x00c04204da40 by goroutine 6:
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Start()
D:/Dropbox/Go/src/gopkg.in/cheggaaa/pb.v1/pb.go:115 +0xc9
gopkg.in/cheggaaa/pb%2ev1.(*Pool).Add()
D:/Dropbox/Go/src/gopkg.in/cheggaaa/pb.v1/pool.go:35 +0xbf
gopkg.in/cheggaaa/pb%2ev1.StartPool()
D:/Dropbox/Go/src/gopkg.in/cheggaaa/pb.v1/pool.go:18 +0xca
main.showProgress()
D:/Dropbox/Go/src/github.com/djherbis/watch/progress.go:38 +0x171
Hi,
The function for terminal size didn't seem to work for me under OmniOS/SmartOS.
./pb.go:178: undefined: terminalWidth
Can you help me please ?
Its generally better practice to have "UI" like things output to standard error so they don't interfere with piping and such.
Moreover using STDERR allows them still to show up even when the standard out is piped, the way curl does in the following example.
$ curl http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso > output.iso
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 964M 0 506k 0 0 355k 0 0:46:15 0:00:01 0:46:14 355k
I want to pipe my apps results but using this progress bar is currently getting in my way and I can see now option in examining the code. It should at least be an option - I'd argue the default one.
For my usages of pb
with io.Reader
, I always used io.TeeReader
, such as:
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
io.Copy(w, io.TeeReader(r, bar))
Any reason why I should use ProxyReader
instead?
Take the example in the Readme:
package main
import (
"github.com/cheggaaa/pb"
"time"
)
func main() {
count := 100000
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
if launched like: echo | ./test
no progress bar is printed. To fix this you should ask the terminal size to /dev/tty
instead of syscall.Stdin
.
Really appreciate the amount of work that has gone into pb! Wanted to ask, were there plans to put NewProxyReader
back into v2? Now that v2 doesn't conform to io.Writer
we are pretty much stuck (since you can't wire up your own io.TeeReader
I used pb's progress bar with unicode character's prefix, and got multiple lines of output.
my code is below...
package main
import (
"gopkg.in/cheggaaa/pb.v1"
"time"
)
func main() {
count := 100000
// header := "progress" // This works well
header := "進捗" // "progress" in Japanese, this cause ugly
bar := pb.StartNew(count).Prefix(header)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
Like this:
movie.avi 3 / 100 [--> ] 3.00 % 2m28s
Similarly, postfix.
Relevant code:
max := 1000
bar := pb.New(max)
for i := 0; i < max; i++ {
time.Sleep(225)
bar.Increment()
// bar.Update() -- makes no friggin' difference
}
bar.Finish()
(from: https://github.com/lavab/worker-sizeup)
Output:
worker-sizeup git:(master) ✗ worker-sizeup
INFO[0000] Connecting to RethinkDB at localhost:12345
INFO[0002] Created temp table tmp_QuOIiziL86T22lib in db staging
1000 / 1000 [==========================================================================================================================================================================================================================================] 100.00 % 2562047h47m16s
INFO[0002] Dropped temp table tmp_QuOIiziL86T22lib in db staging
It doesn't do any live updates, just spits everything out at once at the end. Also notice the messed up total time (2562047h47m16s
).
System:
~ zsh --version
zsh 5.0.8 (x86_64-apple-darwin14.3.0)
~ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)
Copyright (C) 2007 Free Software Foundation, Inc.
~ sw_vers -productVersion
10.10.4
/usr/lib/go/src/pkg/github.com/cheggaaa/pb/pb_x.go:103: undefined: signal.Stop
For a program with items that each take, say, a few seconds to complete, the estimated time left correctly decreases the instant a new item is done, but in between items, it increases. (Basically, the library will print something like: “0:30… 0:31… 0:32… [new item] 0:27… 0:28… 0:29… [new item] 0:24…”)
From reading the source code, I have the impression that it is because it does not keep track of when the last item was completed. Consequently, the time spent since then counts toward the average time per item, instead of being subtracted.
What also seems to support that hypothesis is that the increase gets slower as more items are completed.
To summarize, I think that the correct formula would be:
average_time_per_item = time_spent_before_last_item_completed / number_of_items_completed
time_left = average_time_per_item × number_of_items_left − time_spent_since_last_completed
But instead, the current code is equivalent to this:
total_time = time_spent_before_last_item_completed + time_spent_since_last_item_completed
average_time_per_item = total_time / number_of_items_completed
time_left = average_time_per_item × number_of_items_left
Might be nice to allow fancy unicode symbols for a smoother look similar to Python's tqdm
With unicode multiple characters can represent percentages.
A simple solution would be to allow extra characters in bar.Format and just split all the middle characters into percentage groups.
bar.Format("[█▉▊▋▌▍▎▏ ]")
https://github.com/pypa/pip/blob/develop/pip/_vendor/progress/bar.py#L63
Looks like a race condition recently appeared:
$ go test --race
==================
WARNING: DATA RACE
Write by goroutine 12:
github.com/cheggaaa/pb.(*ProgressBar).write()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:329 +0x1273
github.com/cheggaaa/pb.(*ProgressBar).Update()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:358 +0xb2
github.com/cheggaaa/pb.(*ProgressBar).writer()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:369 +0x40
Previous write by goroutine 11:
github.com/cheggaaa/pb.(*ProgressBar).write()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:329 +0x1273
github.com/cheggaaa/pb.(*ProgressBar).Finish.func1()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:206 +0x7e
sync.(*Once).Do()
/build/golang-5f4oce/golang-1.5.2/src/sync/once.go:44 +0xf6
github.com/cheggaaa/pb.(*ProgressBar).Finish()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:211 +0x78
github.com/cheggaaa/pb.Test_Width()
/home/pilot/go/src/github.com/cheggaaa/pb/pb_test.go:33 +0x16f
testing.tRunner()
/build/golang-5f4oce/golang-1.5.2/src/testing/testing.go:456 +0xdc
Goroutine 12 (running) created at:
github.com/cheggaaa/pb.(*ProgressBar).Start()
/home/pilot/go/src/github.com/cheggaaa/pb/pb.go:111 +0x153
github.com/cheggaaa/pb.Test_Width()
/home/pilot/go/src/github.com/cheggaaa/pb/pb_test.go:31 +0x153
testing.tRunner()
/build/golang-5f4oce/golang-1.5.2/src/testing/testing.go:456 +0xdc
Goroutine 11 (finished) created at:
testing.RunTests()
/build/golang-5f4oce/golang-1.5.2/src/testing/testing.go:561 +0xaa3
testing.(*M).Run()
/build/golang-5f4oce/golang-1.5.2/src/testing/testing.go:494 +0xe4
main.main()
github.com/cheggaaa/pb/_test/_testmain.go:70 +0x20f
==================
2000 / 5000 [===============================================================================================================>------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 40.00 % 2562047h47m16s
2000 / 5000 [oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo] 40.00 % 2562047h47m16s
PASS
Found 1 data race(s)
exit status 66
FAIL github.com/cheggaaa/pb 1.016s
This also results in our own tests failing, so we've had to pin to da1f27a which didn't have the race.
I've a program where bar.Increment() is in goroutine.
I've check program with -race
WARNING: DATA RACE
Read by goroutine 7:
github.com/cheggaaa/pb.(_ProgressBar).GetWidth()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:327 +0x37
github.com/cheggaaa/pb.(_ProgressBar).write()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:227 +0x72
github.com/cheggaaa/pb.(_ProgressBar).Update()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:344 +0x7d
github.com/cheggaaa/pb.(_ProgressBar).writer()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:351 +0x40
Goroutine 7 (running) created at:
github.com/cheggaaa/pb.(*ProgressBar).Start()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:105 +0x150
github.com/cheggaaa/pb.StartNew()
/home/julien/go/src/github.com/cheggaaa/pb/pb.go:53 +0x3c
main.main()
How can I correct this ?
I'm trying to use pb
in a project where I don't want it to print to stdout, instead I want to save pb
output in a variable and write it somewhere else, of course this variable will be updated each time pb
refreshes, so my refresh rate will be way less than the default which is 200ms.
I can't seem to find a method that would return the current state of the progress bar
If I want to use multiple progress bars, can I create a list with each bar pb.New(200).Prefix(name)
and then call StartPool and pass the list? Can the same be done for for _, bar := range []*pb.ProgressBar{first, second, third}
Before you scream "you need to call bar.Start()!" hear me out.
I'm running the example exactly as provided in your README.md (except with a smaller count so I don't have to wait as long):
$ cat bin/testpb.go
package main
import (
"gopkg.in/cheggaaa/pb.v1"
"time"
)
func main() {
count := 1000
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
But when I run it it doesn't output anything until the very end, where it outputs 100%:
$ go run bin/testpb.go
1000 / 1000 [==================================] 100.00% 3s
The End!
I'm on Arch Linux installed on VirtualBox using rxvt-unicode as my terminal, inside a tmux session (though I can confirm that it doesn't work outside of the tmux session either). Please let me know what other information you need to debug this.
It might be more natural for ProgressBar to accept a reader (either as an exported member variable or as an unexported member variable and an exported setter), and then implement Read itself instead of having the separate Reader type.
go test -race -count 1000 -v . -run TestWriteRace
func TestWriteRace(t *testing.T) {
outBuffer := &bytes.Buffer{}
totalCount := 20
bar := New(totalCount)
bar.Output = outBuffer
bar.Start()
var wg sync.WaitGroup
for i := 0; i < totalCount; i++ {
wg.Add(1)
go func() {
bar.Increment()
time.Sleep(250 * time.Millisecond)
wg.Done()
}()
}
wg.Wait()
bar.Finish()
}
==================
WARNING: DATA RACE
Read at 0x00c420186358 by goroutine 31:
runtime.slicecopy()
/usr/local/Cellar/go/1.8/libexec/src/runtime/slice.go:160 +0x0
bytes.(*Buffer).grow()
/usr/local/Cellar/go/1.8/libexec/src/bytes/buffer.go:110 +0x492
bytes.(*Buffer).Write()
/usr/local/Cellar/go/1.8/libexec/src/bytes/buffer.go:137 +0x60
fmt.Fprintln()
/usr/local/Cellar/go/1.8/libexec/src/fmt/print.go:248 +0xad
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Finish.func1()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:254 +0x141
sync.(*Once).Do()
/usr/local/Cellar/go/1.8/libexec/src/sync/once.go:44 +0xe1
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Finish()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:259 +0x8b
gopkg.in/cheggaaa/pb%2ev1.TestWriteRace()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb_test.go:42 +0x1b8
testing.tRunner()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
Previous write at 0x00c420186358 by goroutine 32:
runtime.slicecopy()
/usr/local/Cellar/go/1.8/libexec/src/runtime/slice.go:160 +0x0
bytes.(*Buffer).Write()
/usr/local/Cellar/go/1.8/libexec/src/bytes/buffer.go:138 +0xeb
fmt.Fprint()
/usr/local/Cellar/go/1.8/libexec/src/fmt/print.go:216 +0xad
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).write()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:414 +0xa60
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Update()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:445 +0x84
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).refresher()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:472 +0x130
Goroutine 31 (running) created at:
testing.(*T).Run()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:697 +0x543
testing.runTests.func1()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:882 +0xaa
testing.tRunner()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
testing.runTests()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:888 +0x4e0
testing.(*M).Run()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:822 +0x1c3
main.main()
gopkg.in/cheggaaa/pb.v1/_test/_testmain.go:68 +0x20f
Goroutine 32 (finished) created at:
gopkg.in/cheggaaa/pb%2ev1.(*ProgressBar).Start()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb.go:135 +0x15a
gopkg.in/cheggaaa/pb%2ev1.TestWriteRace()
/Users/jbean/gocode/src/gopkg.in/cheggaaa/pb.v1/pb_test.go:31 +0xfa
testing.tRunner()
/usr/local/Cellar/go/1.8/libexec/src/testing/testing.go:657 +0x107
Hi,
I'd like to have this amazing progress bar in my project but I don't get it working. Probably I'm doing something wrong; I'm new in the go world.
My code:
func downloadFile(filepath string, url string) error {
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// create and start bar
bar := pb.New64(resp.ContentLength).SetUnits(pb.U_BYTES).Start()
// create proxy reader
reader := bar.NewProxyReader(resp.Body)
// and copy from pb reader
_, err = io.Copy(out, reader)
if err != nil {
return err
}
return nil
}
If I download something small it doesn't work:
start download https://storage.googleapis.com/kubernetes-release/release/stable.txt
0 B / 7 B [-----------------------------------------------------------------------------------------------------------------------------------------] 0.00%
If it's something bigger it doesn't get to 100%:
start download https://github.com/harbur/captain/releases/download/v0.8.0/captain-Darwin-x86_64
8.40 MB / 9.40 MB [=================================================================================================================>-------------] 89.30% 0
Note that 89.3
is not always the same. If I execute again it will be another number.
The 7B
and 9.40MB
are both correct, so the content length works fine.
It looks like the first part of download is not taken into account. I don't know what I'm doing wrong. Could you help me please?
Thanks
I'm using:
Hey,
first of all big 👍 for pb. I'm pretty sure it's something I'm doing wrong but I didn't know where to ask. Already tried gophers slack but did not get any solution there. I'm trying to upload a file and show a progress bar during upload. Here is my code:
func uploadSingleFile(fieldname string, file io.Reader, size uint64) (*http.Response, error) {
var b bytes.Buffer
mw := multipart.NewWriter(&b)
ff, err := mw.CreateFormFile("", fieldname)
if err != nil {
return nil, err
}
if _, err := io.Copy(ff, file); err != nil {
return nil, err
}
if err := mw.Close(); err != nil {
return nil, err
}
bar := pb.New(int(size)).SetUnits(pb.U_BYTES)
bar.Start()
defer bar.Finish()
reader := bar.NewProxyReader(&b)
return http.Post(fmt.Sprintf("http://%s/upload", ip), mw.FormDataContentType(), reader)
}
It all works until the file reaches 100%. Then everything stops and I have to kill the process. I'm looping over multiple files and file upload for the second file never starts. Any ideas?
Thank you very much,
Mirco
Here is the output of the error
created by github.com/cheggaaa/pb.(*ProgressBar).Start
/usr/lib/go/src/pkg/github.com/cheggaaa/pb/pb.go:85 +0x77
goroutine 4 [syscall]:
created by addtimer
/home/michael/DPKG/golang/src/pkg/runtime/ztime_amd64.c:72
goroutine 5 [syscall]:
syscall.Syscall6()
/home/michael/DPKG/golang/src/pkg/syscall/asm_linux_amd64.s:40 +0x5
syscall.EpollWait(0xf800000007, 0xf84009d170, 0xa0000000a, 0xffffffff, 0xc, ...)
/usr/lib/go/src/pkg/syscall/zerrors_linux_amd64.go:1781 +0xa1
net.(*pollster).WaitFD(0xf84009d160, 0xf84005c3c0, 0x0, 0x0, 0x0, ...)
/usr/lib/go/src/pkg/net/fd_linux.go:146 +0x110
net.(*pollServer).Run(0xf84005c3c0, 0x0)
/usr/lib/go/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
/usr/lib/go/src/pkg/net/newpollserver.go:35 +0x382
goroutine 7 [runnable]:
net/http.(*persistConn).readLoop(0xf8401673c0, 0x0)
/usr/lib/go/src/pkg/net/http/transport.go:605 +0x505
created by net/http.(*Transport).getConn
/usr/lib/go/src/pkg/net/http/transport.go:382 +0x5df
goroutine 8 [finalizer wait]:
created by runtime.gc
/home/michael/DPKG/golang/src/pkg/runtime/mgc0.c:882
It runs into this error at this point everytime, is it a problem with your code maybe?
I dont see how hanging on a bar.increment() could crash it or anything?
It would be awesome if you could look into this, Thanks!
When resuming a download I want to set the currentValue to the already finished amount.
But bar.Set64(123)
will mess up the speed estimation for some time.
There should be the possibility to set a startvalue without affecting the speed estimation.
Thanks for the great library.
Hello Sergey!
Please add NetBSD support to pb.
In order to do that just add "netbsd" (between freebsd and openbsd to keep it sorted asciibetically ;)) to pb_nix.go and pb_x.go.
I have tested that on NetBSD/amd64 7.99.4 (-current) with lang/go 1.4.1 using odeke-em/drive.
Thanks in advance for your attention!
Ciao,
L.
How to reproduce:
bar := pb.New(1000)
bar.Output = os.Stderr
bar.Start()
Run with:
myprogram > output
Expected:
Progress bar is drawn because output goes to Stderr and Stderr is a terminal.
Actual:
No progress bar is drawn, only counters and percentage is shown.
I am trying to work with a request body and the progress bar is wrapping the body as a reader.
Can the readproxy be upgraded to support readcloser? or can a readcloserproxy be added?
If I write something with longer text postfix previously and then write it with a shorter text, it does not seem to clear the old text out properly
When running the multi-progress bar example on OSX:
go run example.go
panic: Can't get terminal settings: inappropriate ioctl for device
goroutine 1 [running]:
main.main()
/go/src/github.com/c/example/example.go:18 +0x24d
goroutine 19 [syscall]:
os/signal.loop()
/usr/local/Cellar/go/1.5.2/libexec/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
/usr/local/Cellar/go/1.5.2/libexec/src/os/signal/signal_unix.go:28 +0x37
exit status 2
Built using standard go build .
under Go 1.5.2
Hi there,
I have a list of files being downloaded by different go routines...
for i := 0; i < len(urls); i++ {
go func() { c <- download(urls[i])() }()
}
I added the pb()
implementation and it shows the progress bar, but it only displays in the same line...
// Sets the index of the progress, which gives the line position after the current terminal position.
func (pb *ProgressBar) SetIndex(index int) {}
This is similar to Docker's progress bars while pulling images...
[boot-1.pkg] 3.66 MB / 128.94 MB [==>------------------------------------------------] 2.84 % 759.61 KB/s 2m48s
[boot-2.pkg] 23.66 MB / 48.94 MB [===================>-------------------] 45.84 % 629.61 KB/s 2m48s
[boot-3.pkg] 30.00 MB / 300.94 MB [=====>------------------------------------------] 10.84 % 459.61 KB/s 2m48s
thanks!
Marcello
It seems that on OSX, the ioctl syscall is number 54, but currently, 16 is used from pb_nix.go. This in turn causes terminalWidth() to error out and not return a valid value.
Changing pb_x.go to just use syscall.SYS_IOCTL fixes this on Darwin (and thus allows the printing of the progress bar). (I assume this is fine on other platforms but haven't tested it.)
Thanks for the awesome project. Unfortunately, it does not work on my system.
λ go get
# github.com/cheggaaa/pb
..\..\cheggaaa\pb\pb_win.go:45: undefined: word
λ go run foo
# github.com/cheggaaa/pb
..\..\cheggaaa\pb\pb_win.go:45: undefined: word
Windows 10x64, Go 1.6. Let me know if you need anything else.
Edit: After fixing this by adding type word int16
, I now get pb_win.go:60: undefined: buffer in buffer.dwSize
.
I have a (admittedly uncommon) situation: I don't know the Total
value beforehand, so I create a bar with Total=0
, because I want to show the user that some progress is being made. After a while, I asynchronously acquire the size in a different goroutine; I currently set it manually into the progress bar with bar.Total = x
, and it seems to work, but it's marked as data-race, as there are many other goroutines writing into the bar for updating it, so the Total
variable is being read/write in a racy way.
Would it make sense to add a method SetTotal()
to change the total with an atomic operation, and then always use atomic operations to read it? I can contribute a patch if you want.
Please use semantic versioning:
Thanks.
Sample code:
bar := pb.New64(size)
bar.Output = os.Stderr
bar.ShowSpeed = true
bar.Start()
This produces the following output on OSX 10.11.2 and iTerm:
141680640 / 3839401984 [===>------------------------------------------------------------------------------] 3.69 % 29478097/s2m2s
Should there be a space between "/s" and "2m2s"?
If unit is set to pb.U_BYTES
:
106.88 MB / 3.58 GB [==>------------------------------------------------------------------------------------] 2.92 % 28.09 MB2m3s
Should there be "/s" and at least one space before the time estimate?
Hi,
If I'm scanning the file system for mp3s to process (for example), and I'd like to show a progress complete. As the scanning starts, I will find 1 mp3 and begin to process it so the bar could show 1/1. But then 9 more mp3s could be found. I'd like the bar to reset it self to 1/10. And so on. Is something like this possible? Eventually, all mp3s will be found. Say 1000 of them and I'd like to show the progress of them being processed.
Thanks!
Hi there,
I was wondering if you knew of a way to make the progress bar actually update "in-place" in windows?
On OS X, the progress bar behaves exactly as I'd expect, i.e. It prints the bar to the console and then updates it with each increment.
On Windows, however, a new progress bar just gets re-printed to the screen with each update, so you end up with a screen full of static progress bars, like this:
I've looked through options and existing issues to see if there's some config option I can use to tweak this, but I haven't found anything so far. Do you have any suggestions?
Thank you!
After cloning I did the following:
$ cd pb/example
$ go build -race
$ ./example
4886 / 5000 [=======================================================================================================================>--] 97.72 % 0==================
WARNING: DATA RACE
Write by main goroutine:
github.com/cheggaaa/pb.(*ProgressBar).Finish()
/home/christian/gocode/src/github.com/cheggaaa/pb/pb.go:189 +0x3b
github.com/cheggaaa/pb.(*ProgressBar).FinishPrint()
/home/christian/gocode/src/github.com/cheggaaa/pb/pb.go:198 +0x38
main.main()
/home/christian/git/pb/example/pb.go:29 +0x12b
Previous read by goroutine 5:
github.com/cheggaaa/pb.(*ProgressBar).writer()
/home/christian/gocode/src/github.com/cheggaaa/pb/pb.go:328 +0x3b
Goroutine 5 (running) created at:
github.com/cheggaaa/pb.(*ProgressBar).Start()
/home/christian/gocode/src/github.com/cheggaaa/pb/pb.go:101 +0x143
main.main()
/home/christian/git/pb/example/pb.go:24 +0xc7
==================
5000 / 5000 [========================================================================================================================] 100.00 % 5s
The End!
Found 1 data race(s)
Hi,
when passing a file size of 15762329 (return of fi.Size()
) to:
bar = pb.New64(fi.Size()).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
I get the following panic:
panic: runtime error: makeslice: len out of range
goroutine 15727 [running]:
panic(0x6ee280, 0xc420400250)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
strings.Repeat(0x74b1d0, 0x1, 0xfffffffffffffffd, 0x7, 0xc4203b00a0)
/usr/local/go/src/strings/strings.go:420 +0x49
github.com/cheggaaa/pb.(*ProgressBar).write(0xc4200ae000, 0x0)
/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:368 +0xa6c
github.com/cheggaaa/pb.(*ProgressBar).Update(0xc4200ae000)
/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:410 +0x5d
github.com/cheggaaa/pb.(*ProgressBar).Start(0xc4200ae000, 0x74db1e)
/home/hasan/gocode/src/github.com/cheggaaa/pb/pb.go:122 +0x95
...datastores.(*HTTPDataStore).Write.func1(0xc420100050, 0xc420366380, 0xc42011c040, 0xc4203cc390, 0xc4200ae000, 0xc42011c050, 0xc420400090, 0xc4203062a0)
/home/hasan/gocode/src/:127 +0x1a5
created by ...datastores.(*HTTPDataStore).Write
/home/hasan/gocode/src/...rest-http.go:134 +0x4e8
make: *** [test] Error 2
The FinishPrint method currently writes to os.Stdout instead of pb.Output:
// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
pb.Finish()
fmt.Println(str)
}
Instead of using the global average time per entry to calculate the remaining time, using EWMA would give more weight to recent times per entry and would likely provide a more accurate estimate.
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.