I was going through this document related to timeouts and deadlines for HTTP servers in Go. It is a good doc, but I have one question on http.TimeoutHandler
.
func slowHandler(w http.ResponseWriter, req *http.Request) {
time.Sleep(10 * time.Second)
log.Print("Slow API call done after 10 seconds")
io.WriteString(w, "I am slow!\n")
}
func main() {
srv := http.Server{
Addr: ":8888",
WriteTimeout: 5 * time.Second,
Handler: http.TimeoutHandler(http.HandlerFunc(slowHandler), 1*time.Second, "Timeout!\n"),
}
if err := srv.ListenAndServe(); err != nil {
fmt.Printf("Server failed: %s\n", err)
}
}
In the doc, it is mentioned that
After a second, our TimeoutHandler will kick in, stop processing the slowHandler, and return a plain “Timeout!” message
curl request output:
# time curl localhost:8888
* Trying 127.0.0.1:8888...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 503 Service Unavailable
< Date: Wed, 14 Dec 2022 10:19:15 GMT
< Content-Length: 9
< Content-Type: text/plain; charset=utf-8
<
Timeout!
* Connection #0 to host localhost left intact
curl localhost:8888 -v 0.01s user 0.01s system 1% cpu 1.018 total
Indeed, the response is sent back in 1 sec.
But I also noticed that I got this message in server logs after approx 10 seconds.
2022/12/14 15:49:24 Slow API call done after 10 seconds
15:49:24 in GMT would be 10:19:24
So, I guess the slowHandler
was still processing the request in the background and wasn't canceled by TimeoutHandler. It was still running in the background.
Am I understanding this correctly? And if so, then what would happen if slowHandler
has an infinite loop - something like this?
func slowHandler(w http.ResponseWriter, req *http.Request) {
for {} //infinite loop
log.Print("infinite loop")
io.WriteString(w, "I am slow!\n")
}
Will it keep running forever in the background?