Пламен обнови решението на 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
+}
