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.91k stars 1.76k forks source link

Started receiving ErrConnectionClosed error on version 1.56.0 #1875

Closed chlp closed 1 month ago

chlp commented 1 month ago

After upgrading to version 1.56.0, started encountering error ErrConnectionClosed

ErrConnectionClosed = errors.New("the server closed connection before returning the first response byte. " +
        "Make sure the server returns 'Connection: close' response header before closing the connection")

In my case, I was sending a POST request. There is an inverse correlation between the error rate and RPS:

Rolled back to version 1.55.0, and the errors disappeared completely.

newacorn commented 1 month ago

In version 1.56.0, for non-idempotent requests, the framework will no longer automatically make retry decisions for users regardless of the error encountered. When the newly added field RetryIfErr is not configured by the user, the default retry strategy is to never retry non-idempotent requests.

    cli := HostClient{RetryIfErr: func(request *Request, attempts int, err error) (resetTimeout bool, retry bool) {
        isIdempotent := request.Header.IsGet() || request.Header.IsHead() || request.Header.IsPut()
        retry = true
        if !isIdempotent && err != io.EOF {
            retry = false
        }
        return
    }}

Defining RetryIfErr as shown below can replicate the behavior of version 1.55.0.

chlp commented 1 month ago

@newacorn wow, I see. I'll give it a try and come back to share results. Thank you so much!

chlp commented 1 month ago

yeah, it works, thanks again!

    fasthttp.Client{
        RetryIfErr: func(req *fasthttp.Request, attempts int, err error) (resetTimeout bool, retry bool) {
            if err == io.EOF {
                return false, true
            }
            return false, false
        },
    }