Hello 馃憢
I'm playing with the timeout settings and I'm not sure if the following snippet results in the correct behavior.
package main
import (
"fmt"
"log"
"time"
"github.com/valyala/fasthttp"
)
func main() {
server := &fasthttp.Server{
Handler: func(ctx *fasthttp.RequestCtx) {
fmt.Println("Sleeping for 3 seconds...")
time.Sleep(3 * time.Second)
ctx.Response.SetBodyString("Hello, World!")
},
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
IdleTimeout: 1 * time.Second,
}
log.Fatal(server.ListenAndServe(":3000"))
// http://localhost:3000/ -> "Hello, World!"
}
I would assume it would behave just like the WriteTimeout in net/http and throws an error/timeout, but it doesn't.
Maybe I'm missing something here, but I thought I should ask in case it's a bug in pipeconns.go#updateTimer
just tested all fasthttp versions, in my opinion behaviour has never been correct
would say the error is that the handler is executed before the write timeout is set
func (s *Server) serveConn(c net.Conn) (err error) {
....
// If a client denies a request the handler should not be called
if continueReadingRequest {
s.Handler(ctx)
}
timeoutResponse = ctx.timeoutResponse
if timeoutResponse != nil {
ctx = s.acquireCtx(c)
timeoutResponse.CopyTo(&ctx.Response)
if br != nil {
// Close connection, since br may be attached to the old ctx via ctx.fbr.
ctx.SetConnectionClose()
}
}
...
if writeTimeout > 0 {
if err := c.SetWriteDeadline(time.Now().Add(writeTimeout)); err != nil {
panic(fmt.Sprintf("BUG: error in SetWriteDeadline(%s): %s", writeTimeout, err))
}
}
would say it must be registered just before the handler is executed, but iam not an expert for this code
func (s *Server) serveConn(c net.Conn) (err error) {
....
if writeTimeout > 0 {
if err := c.SetWriteDeadline(time.Now().Add(writeTimeout)); err != nil {
panic(fmt.Sprintf("BUG: error in SetWriteDeadline(%s): %s", writeTimeout, err))
}
}
// If a client denies a request the handler should not be called
if continueReadingRequest {
s.Handler(ctx)
}
...
i think net/http does the same, they first register the read timeout timer, then at the end after reading the request the write timeout timer with a defer function, just before they execute the actual handler, as far as i can tell from the code of net/http
For net/http the WriteTimeout includes the time for the handler to process the request. For fasthttp this is not the case. For fasthttp it is really only a timeout for writing the response to the client. It is started when your handler returns. This is a design decision valyala took in the past that would be impossible to change now without breaking fasthttp for almost all our users.
The fasthttp documentation for WriteTimeout clearly states: It is reset after the request handler has returned.
While the net/http documentation for WriteTimeout also clearly states: It is reset whenever a new request's header is read.
ok thx
Thanks for clarifying 馃憤 @erikdubbelboer