mirror of
https://github.com/nxshock/gwp.git
synced 2024-11-27 03:31:02 +05:00
Always update progress text at finish
This commit is contained in:
parent
ed1db97396
commit
267c3604e6
58
gwp.go
58
gwp.go
@ -15,6 +15,10 @@ type WorkerPool struct {
|
|||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
EstimateCount int
|
EstimateCount int
|
||||||
|
|
||||||
|
processedCount int // processed jobs count
|
||||||
|
errorCount int // processed jobs count that returned error
|
||||||
|
currentSpeed float64 // speed calculated for last minute
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates new pool of workers with specified goroutine count.
|
// New creates new pool of workers with specified goroutine count.
|
||||||
@ -32,8 +36,6 @@ func New(threadCount int) *WorkerPool {
|
|||||||
workerPool.wg.Add(threadCount)
|
workerPool.wg.Add(threadCount)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var processedCount int
|
|
||||||
var errorCount int
|
|
||||||
var prevPos int
|
var prevPos int
|
||||||
prevTime := time.Now()
|
prevTime := time.Now()
|
||||||
|
|
||||||
@ -44,40 +46,22 @@ func New(threadCount int) *WorkerPool {
|
|||||||
tickerCalculateEta.Stop()
|
tickerCalculateEta.Stop()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var currentSpeed float64 // jobs per sec
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, endLine)
|
fmt.Fprintf(os.Stderr, endLine)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-tickerUpdateText.C:
|
case <-tickerUpdateText.C:
|
||||||
if workerPool.EstimateCount == 0 {
|
workerPool.printProgress()
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, newLine)
|
|
||||||
fmt.Fprintf(os.Stderr, "Progress: %.1f%% (%d / %d)",
|
|
||||||
float64(processedCount*100)/float64(workerPool.EstimateCount), processedCount, workerPool.EstimateCount)
|
|
||||||
|
|
||||||
if errorCount > 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, " Errors: %d (%.1f%%)",
|
|
||||||
errorCount, float64(errorCount*100)/float64(workerPool.EstimateCount))
|
|
||||||
}
|
|
||||||
if currentSpeed > 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, " ETA: %s at %.2f rps",
|
|
||||||
time.Second*time.Duration(float64(workerPool.EstimateCount-processedCount)/currentSpeed), currentSpeed)
|
|
||||||
}
|
|
||||||
fmt.Fprint(os.Stderr, endLine)
|
|
||||||
case <-tickerCalculateEta.C:
|
case <-tickerCalculateEta.C:
|
||||||
currentSpeed = float64(processedCount-prevPos) * float64(time.Second) / float64(time.Now().Sub(prevTime))
|
workerPool.currentSpeed = float64(workerPool.processedCount-prevPos) * float64(time.Second) / float64(time.Now().Sub(prevTime))
|
||||||
prevPos = processedCount
|
prevPos = workerPool.processedCount
|
||||||
prevTime = time.Now()
|
prevTime = time.Now()
|
||||||
case err := <-workerPool.r:
|
case err := <-workerPool.r:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorCount++
|
workerPool.errorCount++
|
||||||
}
|
}
|
||||||
processedCount++
|
workerPool.processedCount++
|
||||||
case <-workerPool.stopChan:
|
case <-workerPool.stopChan:
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -95,6 +79,26 @@ func New(threadCount int) *WorkerPool {
|
|||||||
return workerPool
|
return workerPool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (workerPool *WorkerPool) printProgress() {
|
||||||
|
if workerPool.EstimateCount == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stderr, newLine)
|
||||||
|
fmt.Fprintf(os.Stderr, "Progress: %.1f%% (%d / %d)",
|
||||||
|
float64(workerPool.processedCount*100)/float64(workerPool.EstimateCount), workerPool.processedCount, workerPool.EstimateCount)
|
||||||
|
|
||||||
|
if workerPool.errorCount > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, " Errors: %d (%.1f%%)",
|
||||||
|
workerPool.errorCount, float64(workerPool.errorCount*100)/float64(workerPool.EstimateCount))
|
||||||
|
}
|
||||||
|
if workerPool.currentSpeed > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, " ETA: %s at %.2f rps",
|
||||||
|
time.Second*time.Duration(float64(workerPool.EstimateCount-workerPool.processedCount)/workerPool.currentSpeed), workerPool.currentSpeed)
|
||||||
|
}
|
||||||
|
fmt.Fprint(os.Stderr, endLine)
|
||||||
|
}
|
||||||
|
|
||||||
// Add sends specified task for execution.
|
// Add sends specified task for execution.
|
||||||
func (workerPool *WorkerPool) Add(f func() error) {
|
func (workerPool *WorkerPool) Add(f func() error) {
|
||||||
workerPool.f <- f
|
workerPool.f <- f
|
||||||
@ -106,4 +110,6 @@ func (workerPool *WorkerPool) CloseAndWait() {
|
|||||||
workerPool.wg.Wait()
|
workerPool.wg.Wait()
|
||||||
workerPool.stopChan <- struct{}{}
|
workerPool.stopChan <- struct{}{}
|
||||||
close(workerPool.r)
|
close(workerPool.r)
|
||||||
|
|
||||||
|
workerPool.printProgress()
|
||||||
}
|
}
|
||||||
|
24
gwp_test.go
24
gwp_test.go
@ -1,6 +1,7 @@
|
|||||||
package gwp
|
package gwp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -23,5 +24,28 @@ func TestBasic(t *testing.T) {
|
|||||||
wp.CloseAndWait()
|
wp.CloseAndWait()
|
||||||
|
|
||||||
assert.EqualValues(t, 100, *count)
|
assert.EqualValues(t, 100, *count)
|
||||||
|
assert.EqualValues(t, 100, wp.processedCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorCounter(t *testing.T) {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
wp := New(i)
|
||||||
|
|
||||||
|
for j := 0; j < 100; j++ {
|
||||||
|
n := j
|
||||||
|
wp.Add(func() error {
|
||||||
|
if n%2 == 0 {
|
||||||
|
return errors.New("error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
wp.CloseAndWait()
|
||||||
|
|
||||||
|
assert.EqualValues(t, 100, wp.processedCount)
|
||||||
|
assert.EqualValues(t, 50, wp.errorCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user