diff --git a/go_design_pattern_book/concurrent_pattern/future/main.go b/go_design_pattern_book/concurrent_pattern/future/main.go new file mode 100644 index 0000000..098f98a --- /dev/null +++ b/go_design_pattern_book/concurrent_pattern/future/main.go @@ -0,0 +1,35 @@ +package main + +func main() { + +} + +type SuccessFunc func(string) +type FailFunc func(error) +type ExecuteStringFunc func() (string, error) + +type MaybeString struct { + successFunc SuccessFunc + failFunc FailFunc +} + +func (s *MaybeString) Success(f SuccessFunc) *MaybeString { + s.successFunc = f + return s +} + +func (s *MaybeString) Fail(f FailFunc) *MaybeString { + s.failFunc = f + return s +} + +func (s *MaybeString) Execute(f ExecuteStringFunc) { + go func(s *MaybeString) { + str, err := f() + if err != nil { + s.failFunc(err) + } else { + s.successFunc(str) + } + }(s) +} diff --git a/go_design_pattern_book/concurrent_pattern/future/main_test.go b/go_design_pattern_book/concurrent_pattern/future/main_test.go new file mode 100644 index 0000000..9c77acf --- /dev/null +++ b/go_design_pattern_book/concurrent_pattern/future/main_test.go @@ -0,0 +1,39 @@ +package main + +import "testing" +import "sync" + +func TestStringorError_Execute(t *testing.T) { + future := &MaybeString{} + t.Run("Success Result", func(t *testing.T) { + var wg sync.WaitGroup + wg.Add(1) + future.Success(func(s string) { + t.Log(s) + wg.Done() + }).Fail(func(e error) { + t.Fail() + wg.Done() + }) + future.Execute(func() (string, error) { + return "Hello World", nil + }) + wg.Wait() + }) + t.Run("Failed Result", func(t *testing.T) { + var wg sync.WaitGroup + wg.Add(1) + future.Success(func(s string) { + t.Fail() + wg.Done() + + }).Fail(func(e error) { + t.Log(e.Error()) + wg.Done() + }) + future.Execute(func() (string, error) { + return "", nil + }) + wg.Wait() + }) +} diff --git a/go_design_pattern_book/concurrent_pattern/futurev1/main.go b/go_design_pattern_book/concurrent_pattern/futurev1/main.go new file mode 100644 index 0000000..115e169 --- /dev/null +++ b/go_design_pattern_book/concurrent_pattern/futurev1/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net/http" +) + +// A Future indicates any data that is needed in future but its computation +// can be started in parallel so that it can be fetched from the background when needed. +type data struct { + Body []byte + Error error +} + +func futureData(url string) <-chan data { + c := make(chan data, 1) + go func() { + var body []byte + var err error + resp, err := http.Get(url) + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + c <- data{Body: body, Error: err} + }() + + return c +} + +func main() { + future := futureData("http://test.future.com") + // do many other things + body := <-future + fmt.Printf("response: %#v", string(body.Body)) + fmt.Printf("error: %#v", body.Error) +}