Решение на 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
} {
var (
tasksLength = len(tasks)
taskChannel = make(chan struct {
index int
result string
}, tasksLength*retryLimit)
semaphore = make(chan struct{}, concurrentLimit)
waitSemaphore = make(chan struct{}, concurrentLimit)
)
go func() {
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
}

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

PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.003s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.028s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.034s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.003s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.003s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.095s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.699s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.755s
PASS
ok  	_/tmp/d20161115-21147-1hja5oc	0.203s

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

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

Ралица обнови решението на 15.11.2016 01:27 (преди над 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
+ go func() {
+ 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++ {
+ for j := 0; j < retryLimit; j++ {
- callbackResult.result = tasks[index]()
- taskChannel <- callbackResult
+ callbackResult.result = tasks[index]()
+ taskChannel <- callbackResult
- if callbackResult.result != "" {
- break
+ if callbackResult.result != "" {
+ break
+ }
}
- }
- semaphore <- struct{}{}
- waitSemaphore <- struct{}{}
- }(i)
- }
+ semaphore <- struct{}{}
+ waitSemaphore <- struct{}{}
+ }(i)
+ }
- for i := 0; i < tasksLength; i++ {
- <-waitSemaphore
- }
- close(taskChannel)
- close(semaphore)
- close(waitSemaphore)
+ for i := 0; i < tasksLength; i++ {
+ <-waitSemaphore
+ }
+ close(taskChannel)
+ close(semaphore)
+ close(waitSemaphore)
+ }()
return taskChannel
}

Ралица обнови решението на 15.11.2016 12:42 (преди над 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{}{}
- }
-
go func() {
+ 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
}