Живко обнови решението на 13.11.2016 20:57 (преди над 1 година)
+package main
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan struct {
+ index int
+ result string
+} {
+ chanLessThanLimitGoroutines := make(chan struct{}, concurrentLimit)
+ chanWaitGoroutinesToFinish := make(chan struct{}, len(tasks))
+ results := make(chan struct {
+ index int
+ result string
+ }, len(tasks)*retryLimit)
+ for i := range tasks {
+ chanLessThanLimitGoroutines <- struct{}{}
+ go func(task func() string, indexFunc int) {
+ for j := 0; j < retryLimit; j++ {
+ strResult := task()
+ results <- struct {
+ index int
+ result string
+ }{indexFunc, strResult}
+ if strResult != "" {
+ break
+ }
+ }
+ <-chanLessThanLimitGoroutines
+ chanWaitGoroutinesToFinish <- struct{}{}
+ }(tasks[i], i)
+ }
+ for i := 0; i < len(tasks); i++ {
+ <-chanWaitGoroutinesToFinish
+ }
+ close(results)
+ return results
+}
Добре изглеждащо решение но не изпълняваш една част от условието:
Функцията трябва да връща канала без да изчаква извършването на задачите - за това имаме канала.