Кирил обнови решението на 28.11.2016 23:14 (преди над 1 година)
+package main
+
+import (
+ "fmt"
+ "time"
+)
+
+type Task interface {
+ Execute(int) (int, error)
+}
+
+type PipelineStruct struct {
+ tasks []Task
+}
+
+func (p PipelineStruct) Execute(firstArg int) (int, error) {
+
+ if len(p.tasks) == 0 {
+ return 0, fmt.Errorf("No tasks to execute!")
+ }
+ var taskArg int = firstArg
+ var err error = nil
+
+ n := len(p.tasks)
+
+ for i := 0; i < n; i++ {
+ taskArg, err = p.tasks[i].Execute(taskArg)
+ if err != nil {
+ return taskArg, fmt.Errorf("A task returned an error : %s", err)
+ }
+ }
+
+ return taskArg, nil
+}
+
+func Pipeline(tasks ...Task) Task {
+ pl := PipelineStruct{tasks: make([]Task, 0)}
+
+ for _, task := range tasks {
+ pl.tasks = append(pl.tasks, task)
+ }
+
+ return pl
+}
+
+type FastestStruct struct {
+ tasks []Task
+}
+
+func (f FastestStruct) Execute(firstArg int) (int, error) {
+ if len(f.tasks) == 0 {
+ return 0, fmt.Errorf("No tasks to execute!")
+ }
+
+ type result struct {
+ val int
+ err error
+ }
+ retChan := make(chan result, 1)
+
+ ftask := func(task Task) result {
+ retVal, retErr := task.Execute(firstArg)
+ return result{retVal, retErr}
+ }
+ for _, task := range f.tasks {
+ go func(task Task) {
+ select {
+ case retChan <- ftask(task):
+ default:
+ }
+ }(task)
+ }
+ retStruct := <-retChan
+ return retStruct.val, retStruct.err
+}
+
+func Fastest(tasks ...Task) Task {
+ fast := FastestStruct{tasks: make([]Task, 0)}
+ for _, task := range tasks {
+ fast.tasks = append(fast.tasks, task)
+ }
+ return fast
+}
+
+type TimedStruct struct {
+ task Task
+ timeout time.Duration
+}
+
+func (t TimedStruct) Execute(arg int) (int, error) {
+ type result struct {
+ val int
+ err error
+ }
+ ftask := func(task Task) <-chan result {
+ retChan := make(chan result, 1)
+ go func() {
+ retVal, retErr := task.Execute(arg)
+ retChan <- result{retVal, retErr}
+ }()
+
+ return retChan
+ }
+
+ select {
+ case result := <-ftask(t.task):
+ return result.val, result.err
+ case <-time.After(t.timeout):
+ return 0, fmt.Errorf("Time out!")
+ }
+}
+
+func Timed(task Task, timeout time.Duration) Task {
+ timedStruct := TimedStruct{task, timeout}
+ return timedStruct
+}
Виж последния коментар, който направих във форума: http://fmi.golang.bg/topics/77