Константин обнови решението на 11.11.2016 23:24 (преди над 1 година)
+package main
+
+type funcResult struct {
+        index  int
+        result string
+}
+
+func startTask(task func() string, retryLimit int, index int, resultChan chan<- funcResult, concurrencyChan chan struct{}) {
+        retries := 0
+        result := ""
+        for retries < retryLimit && result == "" {
+                retries++
+                result = task()
+                resultChan <- funcResult{index, result}
+        }
+
+        concurrencyChan <- struct{}{}
+}
+
+func executeTasks(tasks []func() string, concurrentLimit int, retryLimit int, resultChan chan<- funcResult) {
+        currentlyStarted := 0
+        concurrencyChan := make(chan struct{}, concurrentLimit+1)
+
+        for index, task := range tasks {
+                if currentlyStarted >= concurrentLimit {
+                        <-concurrencyChan
+                        currentlyStarted--
+                }
+                currentlyStarted++
+                go startTask(task, retryLimit, index, resultChan, concurrencyChan)
+        }
+
+        // Wait for all currentlyStarted tasks to finish
+        for i := 0; i < currentlyStarted; i++ {
+                <-concurrencyChan
+        }
+
+        close(resultChan)
+}
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan funcResult {
+        resultChan := make(chan funcResult, concurrentLimit)
+        go func() {
+                executeTasks(tasks, concurrentLimit, retryLimit, resultChan)
+        }()
+
+        return resultChan
+}
