Skip to content

Instantly share code, notes, and snippets.

@atotto
Created February 19, 2015 14:15
Show Gist options
  • Save atotto/ff1a41885de8f3903592 to your computer and use it in GitHub Desktop.
Save atotto/ff1a41885de8f3903592 to your computer and use it in GitHub Desktop.
parallel
// http://play.golang.org/p/cwMSE2imEN
package main
import (
"errors"
"fmt"
"sync"
)
func main() {
err := do()
fmt.Println(err)
}
var Areas = []string{"a", "b", "c", "d", "e", "f"}
type request struct {
area string
}
type result struct {
err error
}
func do() error {
req := make(chan request)
stop := make(chan struct{})
res := parallel(func(area string) error {
fmt.Println(area)
if area == "e" {
return errors.New("error")
}
return nil
}, req, stop, 3)
go func() {
for _, area := range Areas {
req <- request{area}
}
}()
for range Areas {
r := <-res
if r.err != nil {
close(stop)
return r.err
}
}
close(stop)
return nil
}
func parallel(fn func(area string) error, req chan request, stop chan struct{}, concurrency int) chan result {
res := make(chan result)
var wg sync.WaitGroup
wg.Add(concurrency)
for c := 0; c < concurrency; c++ {
go func() {
for {
select {
case re := <-req:
err := fn(re.area)
res <- result{err: err}
case <-stop:
break
}
}
wg.Done()
}()
}
go func() {
wg.Wait()
close(res)
}()
return res
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment