Решение на Concurrent Retry Executor от Димо Дрънгов

Обратно към всички решения

Към профила на Димо Дрънгов

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 9 успешни тест(а)
  • 0 неуспешни тест(а)

Код

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{}, concurrentLimit)
doneChannel := make(chan<- struct{}, len(tasks))
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() {
syncChannel <- struct{}{}
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}
}
doneChannel <- struct{}{}
if len(doneChannel) == len(tasks) {

възможно е последните две(или повече) горутини едновременно да достигнат до този ред след и за двете да е вярно условието - при което ще ти гръмне на следващия че затваряш затворен канал.

close(doneChannel)
close(res)
}
} else {
break
}
}
}()
}
for i := 0; i < concurrentLimit; i++ {
<-syncChannel
}
return res
}

Лог от изпълнението

PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.004s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.023s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.021s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.003s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.003s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.053s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.292s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.126s
PASS
ok  	_/tmp/d20161115-21147-1wqxqno	0.203s

История (2 версии и 2 коментара)

Димо обнови решението на 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
+}

Димо обнови решението на 15.11.2016 09:45 (преди над 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{})
-
+ syncChannel := make(chan struct{}, concurrentLimit)
+ doneChannel := make(chan<- struct{}, len(tasks))
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() {
+ syncChannel <- struct{}{}
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}
}
+ doneChannel <- struct{}{}
+ if len(doneChannel) == len(tasks) {

възможно е последните две(или повече) горутини едновременно да достигнат до този ред след и за двете да е вярно условието - при което ще ти гръмне на следващия че затваряш затворен канал.

+ close(doneChannel)
+ close(res)
+ }
} else {
break
}
}
- syncChannel <- struct{}{}
}()
}
-
for i := 0; i < concurrentLimit; i++ {
<-syncChannel
}
- close(res)
return res
-}
+}