This repository was archived by the owner on Oct 6, 2021. It is now read-only.
File tree Expand file tree Collapse file tree 1 file changed +59
-0
lines changed Expand file tree Collapse file tree 1 file changed +59
-0
lines changed Original file line number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments