diff --git a/README.md b/README.md index b1a8bce..9ace33c 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Go常用的、面向工程化和最佳实践的模式套路,包含常见的23 + [发布订阅模式(Pub-Sub)](./gomore/27_messages) + [时差模式(Time Profile)](./gomore/28_profiles) ++ [上下文模式(Context)](./gomore/29_context) ## 参考资料(Design patters Articles) diff --git a/gomore/29_context/README.md b/gomore/29_context/README.md new file mode 100644 index 0000000..66fe232 --- /dev/null +++ b/gomore/29_context/README.md @@ -0,0 +1,3 @@ +# 上下文模式 + +用于取消一个操作,可能是一个http请求,可能是一个Channel消息队列. diff --git a/gomore/29_context/context_test.go b/gomore/29_context/context_test.go new file mode 100644 index 0000000..30bd4b8 --- /dev/null +++ b/gomore/29_context/context_test.go @@ -0,0 +1,54 @@ +package contexts + +import ( + "context" + "fmt" + "net/http" + "testing" + "time" +) + +func TestContext(t *testing.T) { + go func() { + cContext() + }() + + time.Sleep(time.Second) + + reqest, err := http.NewRequest("GET", "http://localhost:8099/hello", nil) // http client get 请求 + assertEq(nil, err) + client := &http.Client{} + ctx, cancel := context.WithCancel(context.Background()) + reqest = reqest.WithContext(ctx) + + go func() { + select { + case <-time.After(2 * time.Second): + cancel() + } + }() + + response, err := client.Do(reqest) + +} + +func hello(w http.ResponseWriter, req *http.Request) { + + ctx := req.Context() + defer fmt.Println("server: hello handler ended") + + select { + case <-time.After(10 * time.Second): + fmt.Fprintf(w, "hello\n") + case <-ctx.Done(): + err := ctx.Err() + fmt.Println("server:", err) + internalError := http.StatusInternalServerError + http.Error(w, err.Error(), internalError) + } +} + +func cContext() { + http.HandleFunc("/hello", hello) + http.ListenAndServe(":8099", nil) +}