valyala / fasthttp

Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
MIT License
21.66k stars 1.75k forks source link

Confusion about timeout #1529

Closed kukayiyi closed 1 year ago

kukayiyi commented 1 year ago

I want to use fasthttp.client.DoTimeout() to implement timeout control. It should return immediately after the given timeout and proceed to the next step. After searching various sources, I only found that I can modify the client’s dial to achieve this, but this is not elegant and loses the meaning of using DoTimeout(). My requirement is to easily set different timeouts for each request. After checking the history versions, I found that this problem might have occurred after #1346 . As a last resort, I had to downgrade my fasthttp to version 1.38.0 in my project to meet my needs. Am I using it wrong?

kukayiyi commented 1 year ago

I have checked the source code and tried to modify readTimeout, writeTimeout and other max* parameters, but none of them work. No matter how other parameters are set, DoTimeout() will follow the time of the client’s dial.

kukayiyi commented 1 year ago

I used the official sample code https://github.com/valyala/fasthttp/blob/master/examples/client/client.go and still have the same problem. Also, GetTimeout has a similar problem. [When the timeout parameter set is less than 3 seconds, it can normally return a timeout, but when it is greater than 3 seconds, it still fails to work

erikdubbelboer commented 1 year ago

I'm not sure I fully understand, can you post some sample code how you are using fasthttp?

kukayiyi commented 1 year ago

I'm not sure I fully understand, can you post some sample code how you are using fasthttp?

var client  = &fasthttp.Client{
    MaxConnsPerHost:           1024, // MaxConnsPerHost  default is 512, increase to 16384
    ReadTimeout:               15 * time.Second,
    WriteTimeout:              15 * time.Second,

    // I set dial as a workaround, but that changes all timeouts
    //Dial: func(addr string) (net.Conn, error) {
    //  return fasthttp.DialTimeout(addr, time.Duration(config.Conf.Server.RequestTimeout)*time.Millisecond)
    //},
    //
}
req := fasthttp.AcquireRequest()
// build req
resp := fasthttp.AcquireResponse()
err := client.DoTimeout(req, resp, 15*time.Second)

I use it like this, but when the access is slow, it will return after 3 seconds, not 15 seconds, unless I set the dial

erikdubbelboer commented 1 year ago

I'm afraid that currently setting the Dial function yourself is the only way to make this work.

The timeout is not propagated to the right place: https://github.com/valyala/fasthttp/blob/d0f2727a4d2c3784cd363d4fd3c31098e8a481fa/client.go#L1912-L1920 A pull request to fix this would be welcome.