http - http.TimeoutHandler 返回但 handlerfunc 继续运行
问题描述
我正在我的http.timeoutHandler
Go Web 服务器中测试,我注意到 3 秒后我的客户端调用收到“ Timeout
”消息,但 2 秒后我可以在服务器上看到消息“我的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!
推荐阅读
- arrays - 在稳定的 Rust 中为大量数组实现特征的惯用方法是什么?
- angular - 量角器 - 从非角度页面切换到角度页面:“等待量角器与页面同步时出错”
- javascript - 为什么当“exact”未打开时,react-router 没有选择不完全匹配的路由?
- java - 使用 jersey 2 客户端上传文件:从 FormDataParam 的输入流转换为文件
- r - 我正在尝试在 R 中创建一个函数,用户必须猜测 1 到 100 之间的数字,直到它正确,但最多 7 次
- ember.js - 将 WSGI 配置为为单个页面应用程序提供单个 index.html 文件
- couchbase - Couchbase 按不在索引中的字段过滤
- python - 如何绘制实时图表
- sql - T SQL 导出到 XML
- java - 用于理解的 Java