Go 示例: 上下文

在之前的示例中,我们学习了如何设置一个简单的 HTTP 服务器。HTTP 服务器对于演示如何使用 context.Context 来控制取消非常有用。一个 Context 在 API 边界和 goroutine 之间传递截止时间、取消信号和其他请求范围的值。

package main
import (
    "fmt"
    "net/http"
    "time"
)
func hello(w http.ResponseWriter, req *http.Request) {

net/http 机制为每个请求创建一个 context.Context,可以通过 Context() 方法获取。

    ctx := req.Context()
    fmt.Println("server: hello handler started")
    defer fmt.Println("server: hello handler ended")

等待几秒钟,然后向客户端发送回复。这可以模拟服务器正在执行的一些工作。在工作期间,注意观察上下文的 Done() 通道,以获取应尽快取消工作并返回的信号。

    select {
    case <-time.After(10 * time.Second):
        fmt.Fprintf(w, "hello\n")
    case <-ctx.Done():

上下文的 Err() 方法返回一个错误,解释了 Done() 通道为何关闭。

        err := ctx.Err()
        fmt.Println("server:", err)
        internalError := http.StatusInternalServerError
        http.Error(w, err.Error(), internalError)
    }
}
func main() {

与之前一样,我们在“/hello”路由上注册我们的处理程序,并开始服务。

    http.HandleFunc("/hello", hello)
    http.ListenAndServe(":8090", nil)
}

在后台运行服务器。

$ go run context-in-http-servers.go &

模拟对 /hello 的客户端请求,在启动后立即按下 Ctrl+C 以发出取消信号。

$ curl localhost:8090/hello
server: hello handler started
^C
server: context canceled
server: hello handler ended

下一个示例:生成进程.