-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: Transport: add a ConnectionManager interface to separate the connection management from http.Transport #22537
Comments
One interesting thing is that there are some existing fields in |
I like where this is going but it's not a full-fledged proposal yet. It is more of a feature request at this point. See the golang-dev thread for questions that would need to be answered in a full-fledged proposal: |
Noted. Let me reword it. |
Please append new comments instead of editing history to keep conversation easier to follow. |
Sure. FYI, I changed the title only. |
Wanted to rekindle this discussion. I took a quick look at the current In principle, we could narrowly define the In the HTTP/1.x code, it basically boils down to isolating code that uses
I could see (parts of) most of these methods forming the basis of the default I also see Regarding the proxy, @tombergan said:
Maybe I don't fully recognize the subtlety here, but at the end of the day getting a proxy connection still seems to boil down to a key and looking up a connection based on that key: func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn, idleSince time.Time) {
key := cm.key()
t.idleMu.Lock()
defer t.idleMu.Unlock()
for {
pconns, ok := t.idleConn[key]
... All interactions with the idle connections seem to be driven by the opaque key. Are there more one needs to be concerned with? |
Any updates on this? |
Any updates on this? All interactions with the idle connections seem to be driven by the opaque key. In some cases,need get idle connection by specific addr |
This is likely to be limiting - the pool needs some way to create connections for cases where we want to prewarm or maintain a certain number of waiting connections at all times. If dialing is left in Transport and not the pool, the Transport will probably need to expose something similar to http2.Transport's NewClientConn()
I'm having trouble understanding if http2 is or is not in scope. The original comment references two http2 tasks, but an API that only exposes Get/Put methods at the net.Conn level isn't a good fit for http2. An API designed for http2 should also be suitable for http1, but the other way around isn't necessarily true. From the perspective of a pool, http1 is similar to http2 if each connection has a one inflight transaction limit. An http2 API will generally need Get to be at the transaction rather than connection level, and instead of Put will need some number of lifecycle callbacks (on complete, on error, etc. depending on what features you want to be able to implement in the pool). The current http2.ClientConnPool API is part of the way there - it has an appropriate Get that does a transaction reservation, but it lacks the lifecycle callbacks. Instead of working from the http1 direction, one way to iterate on this design might be to:
I think that will help land at the minimal API that covers both protocols and supports a variety of custom pool logic. There may be complexities around evolving the current API in that direction, but I think it's hard to reason about that until there's some agreement on what that direction even is. |
Any updates on this? |
http.Transport
gives us a real solid HTTP client functionality and a faithful protocol implementation. The connection pooling/management is also bundled intohttp.Transport
.http.Transport
connection management takes a stance on a few areas. For example,There are real needs and use cases where we need a different behavior there. We may want to limit the number of active connections. We may want to have a different connection pooling policy (e.g. FIFO). But today it is not possible if you use
http.Transport
. The only option is to implement the HTTP client, but we like the protocol implementation that exists inhttp.Transport
.There are several issues filed because of the inability to override or modify the connection management behavior of
http.Transport
:among others.
It would be great if the connection management aspect of
http.Transport
is separated from the protocol aspect ofhttp.Transport
and becomes pluggable (e.g. aConnectionManager
interface). Then we could choose to provide a different connection management implementation and mix it with the protocol support ofhttp.Transport
.The
http.Transport
API would add this new optional field:The connection manager should have a fairly simple API while encapsulating the complex behavior in the implementation. An incomplete API might look like:
It would be a pretty straightforward pool-like API. The only wrinkle might be that it should allow for the possibility that
Get
may be blocking (with a timeout) for certain implementations that want to allow timed waits for obtaining a connection from the connection manager.It'd be great if the current "connection manager" is available publicly so some implementations can start with the base implementation and configure/customize it or override some methods as needed.
The text was updated successfully, but these errors were encountered: