繁体   English   中英

http.TimeoutHandler 返回但 handlerfunc 继续运行

[英]http.TimeoutHandler returns but handlerfunc keeps running

我正在我的 go web 服务器中测试http.timeoutHandler ,我注意到 3 秒后我的客户端调用收到“ Timeout ”消息,但 2 秒后我可以在服务器上看到消息“My func Println ”。 为什么TimeoutHandler没有取消我的func1

这是我正在使用的代码:

package main

import (
        "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)
        }
}

是的,这就是它的工作方式。

当超时发生并且您的处理程序函数仍在运行(尚未返回)时,请求的上下文将被取消。 您的处理程序负责监视 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!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM