Решение на Concurrent Retry Executor от Николай Генов

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

Към профила на Николай Генов

Резултати

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

Код

// Package main is solution by Nikolay Genov of the second problem
// in the course for the Go Programming Language in FMI, Sofia University
package main
type executedTask struct {
index int
result string
}
// ConcurrentRetryExecutor executes concurrently up to `concurrentLimit` number of tasks
// and if a task returns empty string it must retry it until it reaches maximum of
// `retryLimit` number of total executions.
// Returns a read only channel of structure with consecutive `index` of the executed tasks
// and `result` string
func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan executedTask {
executedTasks := make(chan executedTask)
go func() {
semaphore := make(chan struct{}, concurrentLimit)
defer close(executedTasks)
defer close(semaphore)
for i := 0; i < concurrentLimit; i++ {
semaphore <- struct{}{}
defer func() { <-semaphore }()
}
for index, task := range tasks {
index, task := index, task
<-semaphore
go func() {
result := ""
for execCount := 1; result == "" && execCount <= retryLimit; execCount++ {
result = task()
executedTasks <- executedTask{index, result}
}
semaphore <- struct{}{}
}()
}
}()
return executedTasks
}

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

PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.003s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.027s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.023s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.003s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.004s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.136s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.257s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.535s
PASS
ok  	_/tmp/d20161115-21147-3dvypf	0.203s

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

Николай обнови решението на 13.11.2016 20:37 (преди над 1 година)

+// Package main is solution by Nikolay Genov of the second problem
+// in the course for the Go Programming Language in FMI, Sofia University
+package main
+
+type executedTask struct {
+ index int
+ result string
+}
+
+// ConcurrentRetryExecutor executes concurrently up to `concurrentLimit` number of tasks
+// and if a task returns empty string it must retry it until it reaches maximum of
+// `retryLimit` number of total executions.
+// Returns a read only channel of structure with consecutive `index` of the executed tasks
+// and `result` string
+func ConcurrentRetryExecutor(tasks []func() string, concurrentLimit int, retryLimit int) <-chan executedTask {
+ executedTasks := make(chan executedTask)
+ go func() {
+ semaphore := make(chan struct{}, concurrentLimit)
+ defer close(executedTasks)
+ defer close(semaphore)
+ for i := 0; i < concurrentLimit; i++ {
+ semaphore <- struct{}{}
+ defer func() { <-semaphore }()
+ }
+ for index, task := range tasks {
+ index, task := index, task
+ <-semaphore
+ go func() {
+ result := ""
+ for execCount := 1; result == "" && execCount <= retryLimit; execCount++ {
+ result = task()
+ executedTasks <- executedTask{index, result}
+ }
+ semaphore <- struct{}{}
+ }()
+ }
+ }()
+ return executedTasks
+}