-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworkerpool.go
85 lines (70 loc) · 1.24 KB
/
workerpool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package workerpool
import (
"fmt"
"io"
"sync"
"github.com/gosuri/uiprogress"
)
type Pool struct {
jobs []func()
concurrency int
jobChan chan func()
wg sync.WaitGroup
bar *uiprogress.Bar
barOut io.Writer
}
func New(concurrency int) *Pool {
return &Pool{
concurrency: concurrency,
jobChan: make(chan func()),
barOut: nil,
}
}
func (p *Pool) SetBarOut(o io.Writer) {
p.barOut = o
}
func (p *Pool) Add(job func()) {
p.jobs = append(p.jobs, job)
}
func (p *Pool) Run(progress bool) {
if len(p.jobs) < 1 {
return
}
var pgrs *uiprogress.Progress
if progress {
pgrs = uiprogress.New()
if p.barOut != nil {
pgrs.SetOut(p.barOut)
}
pgrs.Start()
p.bar = pgrs.AddBar(len(p.jobs))
p.bar.AppendCompleted()
p.bar.PrependElapsed()
p.bar.PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("Task (%d/%d)", b.Current(), len(p.jobs))
})
}
for i := 0; i < p.concurrency; i++ {
go func() {
p.work(i)
}()
}
p.wg.Add(len(p.jobs))
for _, job := range p.jobs {
p.jobChan <- job
}
close(p.jobChan)
p.wg.Wait()
if pgrs != nil {
pgrs.Stop()
}
}
func (p *Pool) work(i int) {
for job := range p.jobChan {
job()
p.wg.Done()
if p.bar != nil {
p.bar.Incr()
}
}
}