From 821521fb7de50834792633b75ee477fe7069c466 Mon Sep 17 00:00:00 2001 From: Jian Han Date: Sat, 6 Jan 2018 13:53:28 +1000 Subject: [PATCH] divid and conquer finished --- concurrency/subtasks/main.go | 94 ++++++++++++++++++++++++++-------- concurrency/subtasks/subtasks | Bin 0 -> 2300577 bytes 2 files changed, 74 insertions(+), 20 deletions(-) create mode 100755 concurrency/subtasks/subtasks diff --git a/concurrency/subtasks/main.go b/concurrency/subtasks/main.go index 9ff9289..947a1cd 100644 --- a/concurrency/subtasks/main.go +++ b/concurrency/subtasks/main.go @@ -1,6 +1,13 @@ package main -import "github.com/davecgh/go-spew/spew" +import ( + "fmt" + "reflect" + "runtime" + "time" + + "github.com/davecgh/go-spew/spew" +) // https://medium.com/capital-one-developers/buffered-channels-in-go-what-are-they-good-for-43703871828 @@ -11,36 +18,83 @@ import "github.com/davecgh/go-spew/spew" // ideal way to gather the data back from your subtasks. func main() { - evaluators := []Evaluator{google, yahoo, bing} - data := "Query" - r, e := DivideAndConquer(data, evaluators) - spew.Dump(r, e) + type in struct { + a int + b int + } + + type out struct { + source string + result int + } + + evaluators := []Evaluator{ + EvaluatorFunc(func(inV interface{}) (interface{}, error) { + i := inV.(in) + r := i.a + i.b + return out{"Plus", r}, nil + }), + EvaluatorFunc(func(inV interface{}) (interface{}, error) { + i := inV.(in) + r := i.a * i.b + return out{"Multi", r}, nil + }), + EvaluatorFunc(func(inV interface{}) (interface{}, error) { + i := inV.(in) + r := i.a - i.b + return out{"min", r}, nil + }), + EvaluatorFunc(func(inV interface{}) (interface{}, error) { + i := inV.(in) + r := i.a / i.b + return out{"divider", r}, nil + }), + } + + r, errors := DivideAndConquer(in{2, 3}, evaluators, 10*time.Millisecond) + spew.Dump(r, errors) } -var google = func(data interface{}) (interface{}, error) { - return data, nil +type Evaluator interface { + Evaluate(data interface{}) (interface{}, error) + Name() string +} +type EvaluatorFunc func(interface{}) (interface{}, error) + +func (ef EvaluatorFunc) Evaluate(in interface{}) (interface{}, error) { + return ef(in) } -var yahoo = func(data interface{}) (interface{}, error) { - return data, nil +func (ef EvaluatorFunc) Name() string { + return runtime.FuncForPC(reflect.ValueOf(ef).Pointer()).Name() } -var bing = func(data interface{}) (interface{}, error) { - return data, nil -} - -type Evaluator func(data interface{}) (interface{}, error) - -func DivideAndConquer(data interface{}, evaluators []Evaluator) ([]interface{}, []error) { +func DivideAndConquer(data interface{}, evaluators []Evaluator, timeout time.Duration) ([]interface{}, []error) { gather := make(chan interface{}, len(evaluators)) errors := make(chan error, len(evaluators)) for _, v := range evaluators { go func(e Evaluator) { - result, err := e(data) - if err != nil { + // Why not just use an unbuffered channel? The answer is that we don’t want to leak any goroutines. + // While the Go runtime is capable of handling thousands or hundreds of thousands of goroutines at a time, + // each goroutine does use some resources, so you don’t want to leave them hanging around when + // you don’t have to. If you do, a long-running Go program will start performing poorly + ch := make(chan interface{}, 1) + ech := make(chan error, 1) + go func() { + result, err := e.Evaluate(data) + if err != nil { + errors <- err + } else { + ch <- result + } + }() + select { + case r := <-ch: + gather <- r + case err := <-ech: errors <- err - } else { - gather <- result + case <-time.After(timeout): + errors <- fmt.Errorf("%s timeout after %v on %v", e.Name(), timeout, data) } }(v) } diff --git a/concurrency/subtasks/subtasks b/concurrency/subtasks/subtasks new file mode 100755 index 0000000000000000000000000000000000000000..55a9b4c68bc1860f846704701efc7b072c50cbd8 GIT binary patch literal 2300577 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