我写了一个超时中间件。在这个超时中间件中,我创建了一个用于处理 next 处理程序的goroutine,但是在超时发生两秒后,响应返回408超时状态代码,但goroutine在后台运行并执行处理程序链中的下一个处理程序。 那么如何编写正确的超时中间件?
超时中间件:
type TimeoutHandler struct {
Next http.Handler
}
func (handler *TimeoutHandler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
/*if nil 'Next' handler.*/
if handler.Next == nil {
/*delegate to default serve mux.*/
handler.Next = http.DefaultServeMux
}
/*context with timeout.*/
requestContext := request.Context()
timeoutContext, cancelFunction := context.WithTimeout(requestContext, 2*time.Second)
defer cancelFunction()
/*request with new context.*/
request = request.WithContext(timeoutContext)
chanDone := make(chan bool)
go func() {
/*delegate request to `Next` handler*/
handler.Next.ServeHTTP(responseWriter, request)
chanDone <- true
}()
select {
case <-timeoutContext.Done():
/*status 408 request timeout.*/
responseWriter.WriteHeader(http.StatusRequestTimeout)
case <-chanDone:
return
}
}
这些是我遇到的问题:
答案 0 :(得分:1)
我在论坛中找到了更好的解决方案,我希望这个解决方案可以帮助其他新人。
/**
*
*/
type TimeoutHandler struct {
Next http.Handler
}
/**
*
*/
func (h *TimeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
/*nil 'Next' handler.*/
if h.Next == nil {
/*delegate to default serve mux.*/
h.Next = http.DefaultServeMux
}
/*delegate request to new timeout handler.*/
timeoutHandler := http.TimeoutHandler(h.Next, 4 * time.Second, `Request Timeout.`)
timeoutHandler.ServeHTTP(w, r)
}