That's possible, but the rate of occurrence of the issue is low (but 
painful when it happens), and the costs of starting a new TLS connection 
for every HTTP request are significant.  I'm looking for a better way.

Jim

On Tuesday 2 April 2024 at 15:01:30 UTC-6 Sean Liao wrote:

> since you already know the server is problematic, you could just set Close 
> on the original request.
>
> On Tue, Apr 2, 2024, 15:29 Jim Minter <j...@minter.uk> wrote:
>
>> Hello,
>>
>> I was wondering if anyone had any ideas about 
>> https://github.com/golang/go/issues/21978 ("net/http: no Client API to 
>> close server connection based on Response") -- it's an old issue, but it's 
>> something that's biting me currently and I can't see a neat way to solve it.
>>
>> As an HTTP client, I'm hitting a case where some HTTP server instance 
>> behind a load balancer breaks and starts returning 500s (FWIW with no body) 
>> and without the "Connection: close" header.  I retry, but I end up reusing 
>> the same TCP connection to the same broken HTTP instance, so I never hit a 
>> different backend server and my retry policy is basically useless.
>>
>> Obviously I need to get the server owner to fix its behavior, but it 
>> would be great if, as a client, there were a way to get net/http not to 
>> reuse the connection further, in order to be less beholden to the server's 
>> behavior.
>>
>> This happens with both HTTP/1.1 and HTTP/2.
>>
>> If appropriate, I could live with the request to close the connection 
>> racing with other new requests to the same endpoint.  Getting to the point 
>> where 2 or 3 requests fail and then the connection is closed is way better 
>> than having requests fail ad infinitum.
>>
>> http.Transport.CloseIdleConnections() doesn't solve the problem well (a) 
>> because it's a big hammer, and (b) because there's no guarantee that the 
>> connection is idle when CloseIdleConnections() is called.
>>
>> FWIW I can see in `func (pc *persistConn) readLoop()` there's the 
>> following test:
>>
>> ```go
>> if resp.Close || rc.req.Close || resp.StatusCode <= 199 || bodyWritable {
>> // Don't do keep-alive on error if either party requested a close
>> // or we get an unexpected informational (1xx) response.
>> // StatusCode 100 is already handled above.
>> alive = false
>> }
>> ```
>>
>> I imagine that extending that to `if resp.Close || rc.req.Close || 
>> resp.StatusCode <= 199 || bodyWritable || resp.StatusCode >= 500 {` might 
>> probably help this specific case, but I imagine that's an unacceptably 
>> large behavior change for the rest of the world.
>>
>> I'm not sure how else this could be done.  Does anyone have any thoughts?
>>
>> Many thanks for the help,
>>
>> Jim
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/34d597cf-a84c-48eb-b555-537a8768f468n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/34d597cf-a84c-48eb-b555-537a8768f468n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> - sean
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a3d208a6-90c0-42af-9a13-a8f3f0c7b21dn%40googlegroups.com.

Reply via email to