Промежуточный коммит

pull/5/head
Andrey Ivanov 2020-07-21 09:35:35 +03:00 committed by Andrey Ivanov
parent 628c884543
commit bede26dbd0
1 changed files with 18 additions and 12 deletions

View File

@ -9,25 +9,31 @@ import (
var ErrErrorsLimitExceeded = errors.New("errors limit exceeded") var ErrErrorsLimitExceeded = errors.New("errors limit exceeded")
type Task func() error type Task func() error
type Errors struct {
count int
mx sync.Mutex
}
// Run starts tasks in N goroutines and stops its work when receiving M errors from tasks func Run(tasks []Task, n int, m int) error {
func Run(tasks []Task, N int, M int) error { log.Println("Tasks:", len(tasks), "| Goroutines:", n, "| Errors:", m)
log.Println("Tasks:", len(tasks), "| Goroutines:", N, "| Errors:", M) errs := Errors{}
errs := 0 for i := 0; i < len(tasks); i += n {
for i := 0; i < len(tasks); i = i + N {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
for g := 1; g <= N && i+g < len(tasks); g++ { for g := 1; g <= n && i+g < len(tasks); g++ {
wg.Add(1) wg.Add(1)
go func(rt Task, i int, g int, errs *int) { go func(rt Task, errs *Errors) {
if err := rt; err != nil { err := rt
*errs++ if err != nil {
errs.mx.Lock()
errs.count++
errs.mx.Unlock()
} }
wg.Done() wg.Done()
}(tasks[i+g], i, g, &errs) }(tasks[i+g], &errs)
} }
wg.Wait() wg.Wait()
if errs > M { if errs.count > m {
log.Println("Produced", errs, "errors of", M) log.Println("Produced", errs.count, "errors of", m)
return ErrErrorsLimitExceeded return ErrErrorsLimitExceeded
} }
} }