New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: no Client API to close server connection based on Response #21978

Open
mborsz opened this Issue Sep 22, 2017 · 6 comments

Comments

Projects
None yet
6 participants
@mborsz

mborsz commented Sep 22, 2017

What version of Go are you using (go version)?

1.8

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

I'm using http.Client that connects to HTTP/2 server. I would like to prevent reusing the connection if last response had error 500.

I tried to implement something like this, but I failed:

  • Transport.CancelRequest doesn't work for HTTP/2,
  • Request.Cancel works only on a single stream in HTTP/2 connection,
  • CloseIdleConnections won't work if the connection is in use.
  • I also tried to use httptrace.GetConn to steal net.Conn used by the request and close it, but this is against httptrace protocol.

I did small research and I can't find any way to implement such a thing.
This is a feature request to add it.

Background:
I have an environment where I have tcp load balancer with few replicas behind.
While new connections are directed only to healthy replicas, the existing ones are always attached to the same replica (even if it becomes unhealthy).

If http.Client is attached to replica which became unhealthy, reusing the same connection will cause directing request to the same unhealthy instance.
A more reasonable approach in this case is to reconnect so that load balancer can attach a healthy replica.

@ianlancetaylor ianlancetaylor changed the title from No way in HTTP2 for http.Client to close its connection to net/http: no way in HTTP2 for http.Client to close its connection Mar 30, 2018

@ianlancetaylor ianlancetaylor added this to the Go1.11 milestone Mar 30, 2018

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Mar 30, 2018

@bradfitz

This comment has been minimized.

Member

bradfitz commented Apr 3, 2018

I'm not sure this is even HTTP/2 specific. The net/http API doesn't really expose much or any details of the underlying connections. It's mostly a request/response-based API only.

We do have CloseIdleConnections, but that should work the same way between HTTP/1 and HTTP/2. If not, that's a bug and we should fix that, rather than add new API surface.

That said, even with CloseIdleConnections, there's no nice way to do what you're wanting with either HTTP/1 or HTTP/2, as you can't close the connection until it's idle, and by the time it's "idle", another request might've arrived on it.

@rs sent out a document about expanding the HTTP/2 connection pool interface while I was on vacation. See #17776 (comment) and that bug and linked CLs. Maybe this is another use case that design could address. @rs, thoughts?

I suppose one path could be taking advantage of the fact that net/http.(*Response).Body is an interface, and add support for some optional CloseConnection method on it that acts like Close but also nukes the connection.

@gopherbot gopherbot removed the NeedsFix label Apr 3, 2018

@rs

This comment has been minimized.

Contributor

rs commented Apr 12, 2018

If you implement your own connection pool (with the patches I proposed here), you could just remove the connection from the pool when you detect a 500 error. To close the connection, you then call CloseIfIdle in MarkComplete if the connection is not part the pool. This way you will gracefully close the discarded connections once all in-progress streams are completed.

@rsc

This comment has been minimized.

Contributor

rsc commented Jun 11, 2018

Duplicate of #20977.

@rsc rsc closed this Jun 11, 2018

@rs

This comment has been minimized.

Contributor

rs commented Jun 11, 2018

It is not. #20977 is about server closing client connection. Here we are taking about client closing server connection.

@bradfitz

This comment has been minimized.

Member

bradfitz commented Jun 11, 2018

Oh, okay. We were triaging too quickly and I got confused about which bugs were which.

@bradfitz bradfitz reopened this Jun 11, 2018

@bradfitz bradfitz modified the milestones: Go1.11, Go1.12 Jul 9, 2018

@bradfitz bradfitz added the Thinking label Jul 9, 2018

@bradfitz bradfitz changed the title from net/http: no way in HTTP2 for http.Client to close its connection to net/http: no Client API to close server connection based on Response Aug 6, 2018

@rsc rsc modified the milestones: Go1.12, Go1.13 Nov 14, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment