Димо обнови решението на 14.11.2016 23:56 (преди над 1 година)
+package main
+
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan struct {
+ index int
+ result string
+} {
+ res := make(chan struct {
+ index int
+ result string
+ }, len(tasks)*retryLimit)
+ tasksChannel := make(chan struct {
+ f func() string
+ index int
+ }, len(tasks))
+ syncChannel := make(chan struct{})
+
+ for i := 0; i < len(tasks); i++ {
+ tasksChannel <- struct {
+ f func() string
+ index int
+ }{tasks[i], i}
+ }
+
+ close(tasksChannel)
+
+ for i := 0; i < concurrentLimit; i++ {
+ go func() {
+ for {
+ t, ok := <-tasksChannel
+ if ok {
+ funcResult := ""
+ for j := 0; j < retryLimit && funcResult == ""; j++ {
+ funcResult = t.f()
+ res <- struct {
+ index int
+ result string
+ }{t.index, funcResult}
+ }
+ } else {
+ break
+ }
+ }
+ syncChannel <- struct{}{}
+ }()
+ }
+
+ for i := 0; i < concurrentLimit; i++ {
+ <-syncChannel
+ }
+ close(res)
+ return res
+}
Не спазваш частта от условието казваща:
Функцията трябва да връща канала без да изчаква извършването на задачите - за това имаме канала.
възможно е последните две(или повече) горутини едновременно да достигнат до този ред след и за двете да е вярно условието - при което ще ти гръмне на следващия че затваряш затворен канал.