Ралица обнови решението на 14.11.2016 23:59 (преди над 1 година)
+package main
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan struct {
+ index int
+ result string
+} {
+ var (
+ tasksLength = len(tasks)
+ taskChannel = make(chan struct {
+ index int
+ result string
+ }, tasksLength*retryLimit)
+
+ semaphore = make(chan struct{}, concurrentLimit)
+ waitSemaphore = make(chan struct{}, concurrentLimit)
+ )
+
+ for i := 0; i < concurrentLimit; i++ {
+ semaphore <- struct{}{}
+ }
+
+ for i := 0; i < tasksLength; i++ {
+ <-semaphore
+ go func(index int) {
+ var callbackResult struct {
+ index int
+ result string
+ }
+ callbackResult.index = index
+
+ for j := 0; j < retryLimit; j++ {
+
+ callbackResult.result = tasks[index]()
+ taskChannel <- callbackResult
+
+ if callbackResult.result != "" {
+ break
+ }
+ }
+
+ semaphore <- struct{}{}
+ waitSemaphore <- struct{}{}
+ }(i)
+ }
+
+ for i := 0; i < tasksLength; i++ {
+ <-waitSemaphore
+ }
+ close(taskChannel)
+ close(semaphore)
+ close(waitSemaphore)
+
+ return taskChannel
+}
Не спазваш частта от условието казваща:
Функцията трябва да връща канала без да изчаква извършването на задачите - за това имаме канала.