Анатоли обнови решението на 14.11.2016 10:54 (преди над 1 година)
+package main
+
+import (
+        "fmt"
+)
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan struct {
+        index  int
+        result string
+} {
+
+        totalTasks := len(tasks)
+
+        if concurrentLimit > totalTasks || concurrentLimit <= 0 {
+                concurrentLimit = totalTasks
+        }
+
+        if retryLimit < 0 {
+                retryLimit = 0
+        }
+
+        //the results will be sent here
+        resultChan := make(chan struct {
+                index  int
+                result string
+        }, totalTasks*retryLimit+1)
+
+        //no tasks to exec
+        if concurrentLimit == 0 {
+                resultChan <- struct {
+                        index  int
+                        result string
+                }{0, "No task to exec"}
+
+                close(resultChan)
+                return resultChan
+        }
+
+        //used to implement concurrent limit
+        throttlingChan := make(chan bool, concurrentLimit)
препоръчвам ти да ползваш chan struct{}
+
+        for i := 0; i < concurrentLimit; i++ {
+                throttlingChan <- true
+        }
+
+        //used to wait all routines to finish before exit
+        doneChan := make(chan bool, totalTasks)
+
+        //task executor
+        go func() {
+                for idx, task := range tasks {
+                        <-throttlingChan
+
+                        //task
+                        go func(idx int, task func() string) {
+                                taskResult := ""
+
+                                for i := 0; i <= retryLimit; i++ {
+                                        //execute
+                                        taskResult = task()
+
+                                        //send the response
+                                        resultChan <- struct {
+                                                index  int
+                                                result string
+                                        }{idx, taskResult}
+
+                                        //finish if successfull task
+                                        if taskResult != "" {
+                                                break
+                                        }
+                                }
+
+                                throttlingChan <- true
+                                doneChan <- true
+                        }(idx, task)
+                }
+
+                //wait for the last routines to end
+                for i := 0; i < totalTasks; i++ {
+                        <-doneChan
+                }
+
+                //cleanup
+                close(throttlingChan)
+                close(resultChan)
+                close(doneChan)
+        }()
+
+        return resultChan
+}
+
+func main() {
Ма'ни го тоя main
+        results := ConcurrentRetryExecutor([]func() string{}, 2, 3)
+
+        for result := range results {
+                if result.result == "" {
+                        fmt.Printf("Task %d returned an error!\n", result.index+1)
+                } else {
+                        fmt.Printf("Task %d successfully returned '%s'\n", result.index+1, result.result)
+                }
+        }
+
+        fmt.Println("All done!")
+}

препоръчвам ти да ползваш chan struct{}