What operating system and processor architecture are you using (go env)?
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.
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.
The text was updated successfully, but these errors were encountered:
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.
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.