Емил обнови решението на 15.11.2016 11:17 (преди над 1 година)
+package main
+
+type taskDescription struct {
+ index int
+ function func() string
+}
+
+type compoundResult struct {
+ index int
+ result string
+}
+
+func ConcurrentRetryExecutor(tasks []func() string,
+ concurrentLimit int,
+ retryLimit int) <-chan compoundResult {
+ resultsChannel := make(chan compoundResult)
+
+ go func() {
+ tasksChannel := make(chan taskDescription)
+ workerChannel := make(chan int)
+
+ for i := 0; i < concurrentLimit; i++ {
+ go func() {
+ for taskToRun := range tasksChannel {
+ resultString := ""
+ retryCount := retryLimit
+
+ for resultString == "" && retryCount > 0 {
+ resultString = taskToRun.function()
+
+ result := compoundResult{
+ index: taskToRun.index,
+ result: resultString,
+ }
+
+ resultsChannel <- result
+
+ retryCount--
+ }
+ }
+ workerChannel <- 1
+ }()
+ }
+
+ for i, taskFunction := range tasks {
+ tasksChannel <- taskDescription{
+ index: i,
+ function: taskFunction,
+ }
+ }
+ close(tasksChannel)
+
+ for i := 0; i < concurrentLimit; i++ {
+ <-workerChannel
+ }
+ close(workerChannel)
+ close(resultsChannel)
+ }()
+
+ return resultsChannel
+}