为了账号安全,请及时绑定邮箱和手机立即绑定

http.TimeoutHandler 返回但 handlerfunc 继续运行

http.TimeoutHandler 返回但 handlerfunc 继续运行

Go
回首忆惘然 2023-08-21 14:28:40
我正在测试http.timeoutHandler我的Go Web服务器,我注意到3秒后我的客户端调用收到一条“ Timeout”消息,但2秒后我可以在服务器日志上看到消息“My func Println”。为什么TimeoutHandler没有取消我的func1?这是我正在使用的代码:package mainimport (        "fmt"        "io"        "net/http"        "time")func func1(w http.ResponseWriter, req *http.Request) {        time.Sleep(5 * time.Second)        fmt.Println("My func Println")        io.WriteString(w, "My func!\n")}func main() {        srv := http.Server{                Addr:         ":9000",                WriteTimeout: 5 * time.Second,                Handler:      http.TimeoutHandler(http.HandlerFunc(func1), 3*time.Second, "Timeout!\n"),        }        if err := srv.ListenAndServe(); err != nil {                fmt.Printf("Server failed: %s\n", err)        }}
查看完整描述

1 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

是的,这就是它的工作原理。


当超时发生并且您的处理程序函数仍然运行(尚未返回)时,请求的上下文将被取消。您的处理程序负责监视 Context 的 Done 通道,并在请求取消时中止其工作。每个处理程序都在自己的 goroutine 中运行,并且 goroutine 不能从“外部”被终止或中断。


如何做到这一点的示例:


func func1(w http.ResponseWriter, req *http.Request) {

    select {

    case <-time.After(5 * time.Second):

        fmt.Println("My func Println")

        io.WriteString(w, "My func!\n")

    case <-req.Context().Done():

        fmt.Println("Cancelled")

    }

}

这将输出:


Cancelled

如果您将处理程序中的延迟更改为 2 秒:


case <-time.After(2 * time.Second):

输出将是:


My func Println

客户端收到发送的数据:


My func!


查看完整回答
反对 回复 2023-08-21
  • 1 回答
  • 0 关注
  • 77 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信