-
Notifications
You must be signed in to change notification settings - Fork 336
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
http2 internal pool poc #89
Conversation
I'd love to see a better connection pool with warm connections. Currently it takes sometimes more than a minute to connect to Apple. I tried a lot of different settings but no result. |
Thanks for the PR @c3mb0 ! :) |
That's reasonable, I chose reflection over patching to demonstrate the idea and avoid http2 maintenance. However, considering this issue that I came across afterwards, having our own patched http2 to fit our use case seems like the way to go. I'll get to work ASAP, expect an update this week. |
Cool, ideally we will only have to maintain our own patched version until there is consensus that these fields should be made public in the http2 master branch. Hopefully they open the fields up reasonably soon. See related issues golang/go#17776 and golang/go#17775 In the mean time, i've cloned and uploaded the http2 library here https://github.com/sideshow/http2
|
Neat! I'll be sending some PR's your way, would you like to move the discussion over to the other repository or continue from here? If you prefer the former, you can mark this one as closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just discussing defer a potential issue
rf = reflect.Indirect(reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr()))) | ||
rf.SetBool(true) | ||
mu.Unlock() | ||
defer func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think mu
and rf
should be passed as parameters here to avoid issue like this: https://play.golang.org/p/KKaK0776AK
@c3mb0 closing this off. Feel free to start a new PR here or in the other repo. Thanks |
I'm opening this PR to spark some discussion. This code is WIP, it lacks tests and proper flow, however functional.
Here's a small summary of how the http/2 connection pooling works in Go, as far as I understand:
You can browse the code here. Instead of writing a custom connection pool, I'm exploiting reflection here to trigger the 4th step.
First,
CloseIdleConnections
can be called to initialize the transport's internal connection pool, as seen here.The function that checks if a connection is available is here. The most practical field to change in order to mark a connection as unavailable is
closed
. After retrieving and locking appropriate mutexes on both pool and connection level, theclosed
flag for all connections is set totrue
.Following our scenario, the next connection request reaches step 4 since there are no "available" connections (although they are alive and well). Internals create a new connection, and add it to the pool. Since the resulting connection is obtained manually via
GetClientConn
, the returned connection can be pinged periodically in a separate goroutine.Once the deed is done,
closed
flags for all connections in the pool are restored. Since dropped connections are cleaned automatically from the pool, when pinging fails, the desired connection amount can be sustained viaaddNewConn
.Reflected fields seem stable, they haven't been changed in 2 years. Since it is not executing on a hot path, reflect performance is not much of a concern.
Thoughts? Is it worth fleshing out, or would you be against a reflection based solution?