Skip to content
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: add MaxConnLifespan to Transport #46714

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

josephcopenhaver
Copy link

@josephcopenhaver josephcopenhaver commented Jun 12, 2021

Existing implementation appeared to have no way to set a connection
max lifetime. A max lifetime allows for refreshing connection lifecycle
concerns such as dns resolutions for those that need it.

When initialized to a non-zero value the connection will be closed after
the duration has passed. This change is backwards compatible.

Fixes #23427

The only other knob I would like to add to the default transport is an assurance that at most MaxConns # of connections will be opened but I think I can use the round-tripper interface to add this knob as long as the net.Conn interface is always guaranteed to have Close() called.

@google-cla
Copy link

google-cla bot commented Jun 12, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no Used by googlebot to label PRs as having an invalid CLA. The text of this label should not change. label Jun 12, 2021
@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from bb7a404 to 4902316 Compare June 12, 2021 02:57
@google-cla
Copy link

google-cla bot commented Jun 12, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@josephcopenhaver
Copy link
Author

@googlebot I signed it!

@google-cla google-cla bot added cla: yes Used by googlebot to label PRs as having a valid CLA. The text of this label should not change. and removed cla: no Used by googlebot to label PRs as having an invalid CLA. The text of this label should not change. labels Jun 12, 2021
@gopherbot
Copy link
Contributor

This PR (HEAD: 4902316) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

Message from Go Bot:

Patch Set 1:

Congratulations on opening your first change. Thank you for your contribution!

Next steps:
A maintainer will review your change and provide feedback. See
https://golang.org/doc/contribute.html#review for more info and tips to get your
patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.

During May-July and Nov-Jan the Go project is in a code freeze, during which
little code gets reviewed or merged. If a reviewer responds with a comment like
R=go1.11 or adds a tag like "wait-release", it means that this CL will be
reviewed as part of the next development cycle. See https://golang.org/s/release
for more details.


Please don’t reply on this GitHub thread. Visit golang.org/cl/327474.
After addressing review feedback, remember to publish your drafts!

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 4902316 to fea56c1 Compare June 12, 2021 05:05
@gopherbot
Copy link
Contributor

This PR (HEAD: fea56c1) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from fea56c1 to 60f9d00 Compare June 12, 2021 07:39
@gopherbot
Copy link
Contributor

This PR (HEAD: 60f9d00) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 60f9d00 to b78ef9a Compare June 12, 2021 07:45
@gopherbot
Copy link
Contributor

This PR (HEAD: b78ef9a) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from b78ef9a to 88e5505 Compare June 12, 2021 07:51
@gopherbot
Copy link
Contributor

This PR (HEAD: 88e5505) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 88e5505 to 28c82af Compare June 13, 2021 01:42
@gopherbot
Copy link
Contributor

This PR (HEAD: 28c82af) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 28c82af to 984dc1b Compare September 12, 2021 07:42
@gopherbot
Copy link
Contributor

This PR (HEAD: 984dc1b) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 984dc1b to 7cc745d Compare September 12, 2021 07:53
@gopherbot
Copy link
Contributor

This PR (HEAD: 7cc745d) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from 7cc745d to e637fbf Compare February 5, 2022 07:17
@gopherbot
Copy link
Contributor

This PR (HEAD: e637fbf) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@gopherbot
Copy link
Contributor

Message from Damien Neil:

Patch Set 9:

(1 comment)


Please don’t reply on this GitHub thread. Visit golang.org/cl/327474.
After addressing review feedback, remember to publish your drafts!

@leilei911
Copy link

Hi @josephcopenhaver, thanks for creating the PR. I was wondering when you think we could merge the PR. We have a DNS resolution issue with our service and could really use your fix.

Existing implementation appeared to have no way to set a connection
max lifetime. A max lifetime allows for refreshing connection lifecycle
concerns such as dns resolutions for those that need it.

When initialized to a non-zero value the connection will be closed after
the duration has passed. This change is backwards compatible.

Fixes golang#23427
@josephcopenhaver josephcopenhaver force-pushed the jpcope/develop/add-max-http-connection-lifespan branch from e637fbf to a881869 Compare May 4, 2022 04:48
@gopherbot
Copy link
Contributor

This PR (HEAD: a881869) has been imported to Gerrit for code review.

Please visit https://go-review.googlesource.com/c/go/+/327474 to see it.

Tip: You can toggle comments from me using the comments slash command (e.g. /comments off)
See the Wiki page for more info

@josephcopenhaver
Copy link
Author

josephcopenhaver commented May 4, 2022

@leilei911 I am a new contributor to go's standard sdk in general and unfortunately I do not have the influence to provide you with a timeline.

The latest comment from @neild at https://go-review.googlesource.com/c/go/+/327474 indicates that Any new package API needs to go through the proposal process. which shows as resolved and may be in an upcoming candidate patch set if I read this all correctly.

Edit:

I kinda expected more conversation around how to couple such a feature to DNS TTLs a client discovers in the natural flow of things without taking such a simple approach. However most places where go is used at scale can operate just fine with a client override that does not try to couple itself with a DNS request's response. This solves real problems with balancing now where people only have service discovery, so I am for it! Also there is the concern of some hosts being just raw IP addresses where such a thing like DNS does not even come into play, so it does have value if someone uses a non dns backed discovery method.

If the maintainers provide feedback that this feature request should be smarter in any way ( such as allow the value to change over time ), I am open to making improvements. Right now I'm just keeping the patch up up to date with the origin and the ball is in their court unless I have misread anything. :-)

@josephcopenhaver
Copy link
Author

Cross posting from: #23427 (comment)

I wonder how much of this problem is purely one of loadbalancing concepts people may be trying to implement.

If a host record resolves to 3 ip nodes and suddenly we add or remove one, then respectively we need to ensure the new node starts taking requests as soon as we know about it so load spreads ( no need to close connections until we approach the max connection limit or idle timeouts happen ) or remove connections tied to the deregistering ( potentially already deregistered ) ip address.

The latter case of removing a node is trivial and fairly self-correcting before any DNS TTL and refresh cycle would inform us on average.

In the same token, idle connection timeout can create "randomly hot" nodes over time by just the probability of FIFO rotating through connections cyclicly. A max lifespan is a fairly nuclear solution to this problem when perhaps envoy proxy should be the full-featured solution for balancing out-of-app.

For people wanting a solution in the same binary they really probably want LIFO connection queuing under a round-robin ( or some distance/efficiency-aware weighted function ) connection broker over the LIFO queues partitioned by IP. This would allow for any "logically extra" connections the service can live without to end up dying off just by virtue of the connection timeouts.

If DNS appears to remove a host we can assume the DNS source has determined that the host should get phased out and schedule the relevant connections to die as soon as their transactions finish or immediately inform the broker to kill that pool of trusted connections.

As a DNS entry is discovered for a hostname a LIFO queue would be created and added to the connection broker. Load would spread almost immediately across the upstream offering, and old connections no longer getting any use on the other nodes would start to time out and die off, expensive new connection flows continue to be avoided.

Connection max lifetime/reuse is likely not the feature people need or want. ( If you do need/want it cool, my PR offers it! ) It just looks like what we're reaching for in this conversation when we really want to observe+schedule DNS resolution and use that to inform a connection pooling strategy where we can change the implementation of popping and pushing to a queue we maintain externally that is LIFO or FIFO or anything else - but note we need to know the connection's target IP to achieve these goals. It's worth discussing in more detail by persons probably smarter than myself. Typically when users of one of my libs want agency I will happily give them the simplest interface they need to achieve their goals and default the behavior to off. Perhaps the maintainers are willing to do similar here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Used by googlebot to label PRs as having a valid CLA. The text of this label should not change.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

net/http: make Transport's idle connection management aware of DNS changes?
3 participants