Пламен обнови решението на 13.11.2016 23:38 (преди над 1 година)
+package main
+
+type Task struct {
+ index int
+ result string
+}
+
+func main() {}
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan struct {
+ index int
+ result string
+} {
+ ch := make(chan struct {
+ index int
+ result string
+ })
+
+ var limit = make(chan struct{}, concurrentLimit)
+ wg := make(chan struct{})
+
+ var t Task
+
+ go func() {
+ for index, task := range tasks {
+ limit <- struct{}{}
+ go func(index int, task func() string) {
+ defer func() {
+ wg <- struct{}{}
+ }()
+ for i := 0; i < retryLimit; i++ {
+ t.result = task()
+ t.index = index
+ if t.result != "" {
+ ch <- t
+ break
+ }
+ ch <- t
+ }
+ <-limit
+ }(index, task)
+ }
+ }()
+
+ go func() {
+ for i := 0; i < len(tasks); i++ {
+ <-wg
+ }
+ close(ch)
+ }()
+ return ch
+}