Skip to content
This repository was archived by the owner on Oct 6, 2021. It is now read-only.

Commit 6710cdc

Browse files
matteosuppocmaglie
authored andcommitted
initial commit
0 parents  commit 6710cdc

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

cc.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package cc
2+
3+
import "sync"
4+
5+
// Pool manages a pool of concurrent workers. It works a bit like a Waitgroup, but with error reporting and concurrency limits
6+
// You create one with New, and run functions with Run. Then you wait on it like a regular WaitGroup and loop over the errors.
7+
// It's important to loop over the errors because that's what's blocking.
8+
//
9+
// Example:
10+
//
11+
// p := cc.New(4)
12+
// p.Run(func() {
13+
// p.Errors <- afunction()
14+
// })
15+
// p.Wait()
16+
//
17+
// for err := range p.Errors {
18+
//
19+
// }
20+
type Pool struct {
21+
Errors chan error
22+
23+
semaphore chan bool
24+
wg *sync.WaitGroup
25+
}
26+
27+
// New returns a new pool where a limited number (concurrency) of goroutine can work at the same time
28+
func New(concurrency int) *Pool {
29+
wg := sync.WaitGroup{}
30+
p := Pool{
31+
Errors: make(chan error),
32+
33+
semaphore: make(chan bool, concurrency),
34+
wg: &wg,
35+
}
36+
return &p
37+
}
38+
39+
// Wait doesn't block, but ensures that the channels are closed when all the goroutines end.
40+
func (p *Pool) Wait() {
41+
go func() {
42+
p.wg.Wait()
43+
close(p.Errors)
44+
close(p.semaphore)
45+
}()
46+
}
47+
48+
// Run wraps the given function into a goroutine and ensure that the concurrency limits are respected.
49+
func (p *Pool) Run(fn func()) {
50+
p.wg.Add(1)
51+
go func() {
52+
p.semaphore <- true
53+
defer func() {
54+
<-p.semaphore
55+
p.wg.Done()
56+
}()
57+
fn()
58+
}()
59+
}

0 commit comments

Comments
 (0)