Стоян обнови решението на 14.11.2016 23:12 (преди над 1 година)
+package main
+
+type Task struct {
+ index int
+ result string
+}
+
+func createSemaphore(length int) (sem chan struct{}) {
+ sem = make(chan struct{}, length)
+ for i := 0; i < length; i++ {
+ sem <- struct{}{}
+ }
+ return
+}
+
+func executeTask(i int, concurrentLimit int, leftRetries int, tasks []func() string, sem chan struct{}, res chan Task) {
+ <-sem
+ if i < len(tasks)-1 {
+ go executeTask(i+1, concurrentLimit, leftRetries, tasks, sem, res)
+ }
+ taskResult := tasks[i]()
+ res <- Task{index: i, result: taskResult}
+ leftRetries--
+
+ for taskResult == "" && leftRetries > 0 {
+ taskResult = tasks[i]()
+ res <- Task{index: i, result: taskResult}
+ leftRetries--
+ }
+ if i == len(tasks)-1 {
+ for x := 0; x < concurrentLimit-1; x++ {
+ <-sem
+ }
+ close(res)
+ }
+ sem <- struct{}{}
+}
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan Task {
+ sem := createSemaphore(concurrentLimit)
+ res := make(chan Task)
+
+ go executeTask(0, concurrentLimit, retryLimit, tasks, sem, res)
+ return res
+}