如何将context.Done()与嵌套的http中间件一起使用

如何将context.Done()与嵌套的http中间件一起使用,http,go,Http,Go,我想知道在服务器中使用该方法并实现时如何正确地实现/使用该方法,我的目标是在客户机跨嵌套中间件断开连接时取消后续事件 为了进行测试,我创建了以下代码,我不知道这样做是否正确,因为我必须在中创建和来处理请求,将所有这些放在一个wait语句中 package main import ( "fmt" "log" "net/http" "time" ) func hello(w http.ResponseWriter, r *http.Request) { c

我想知道在服务器中使用该方法并实现时如何正确地实现/使用该方法,我的目标是在客户机跨嵌套中间件断开连接时取消后续事件

为了进行测试,我创建了以下代码,我不知道这样做是否正确,因为我必须在中创建和来处理请求,将所有这些放在一个wait语句中

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func hello(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    log.Println("handler started")
    defer log.Println("hander ended")

    ch := make(chan struct{})

    go func() {
        time.Sleep(5 * time.Second)
        fmt.Fprintln(w, "Hello")
        ch <- struct{}{}
    }()

    select {
    case <-ch:
    case <-ctx.Done():
        err := ctx.Err()
        log.Println(err)
        http.Error(w, err.Error(), http.StatusPartialContent)
    }
}

func main() {
    http.HandleFunc("/", hello)
    log.Fatal(http.ListenAndServe(":8080", nil))
}
然后按ctl+c,这将被记录:

2017/07/07 22:22:40 handler started
2017/07/07 22:22:42 context canceled
2017/07/07 22:22:42 hander ended
这是可行的,但是想知道是否应该在每个嵌套处理程序中使用此模式(goroutine和select),或者是否有更好的方法来实现这一点:

ch := make(chan struct{})
go func() {
    // some logic   
    ch <- struct{}{}
}()

select {
case <-ch:
case <-ctx.Done():
    err := ctx.Err()
    log.Println(err)
    http.Error(w, err.Error(), http.StatusPartialContent)
}
ch:=make(chan结构{})
go func(){
//一些逻辑
中国
在Google,我们要求Go程序员将上下文参数作为第一个参数传递给传入和传出请求之间调用路径上的每个函数

--


您传递了上下文,但是否仍需要创建
select{案例我读到它是因为每个异步进程都需要与上下文竞争并提前退出。在严肃的应用程序中,您可能无论如何都需要一个超时子上下文。请您分享一个示例或编写一个基本实现,基本上想知道处理程序的所有代码是否都在一个goruine中:
go-func(ch-chan-struct{}){..
ch := make(chan struct{})
go func() {
    // some logic   
    ch <- struct{}{}
}()

select {
case <-ch:
case <-ctx.Done():
    err := ctx.Err()
    log.Println(err)
    http.Error(w, err.Error(), http.StatusPartialContent)
}