EDIT: See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/516#issuecomment-324173926 for the new direction for this bug.
It looks like datastore#Client.Close() closes the underlying connection. However while reading the doc:
datastore.NewClient actually calls Close() on the client. Which makes me think maybe itSo in the godoc, I don't see any clear guidance on whether:
datastore.Client should be reused (i.e. it maintains a connection pool maybe?)Perhaps clarifying these with some remarks, or fixing either the example code or the Close() godoc would help.
/cc @adams-sarah
Actually found one example where it is closed. https://godoc.org/cloud.google.com/go/datastore#ex-package--Auth But there are other 2-3 more visible examples that it isn't closed.
If a client has a Close method, you should consider it a heavyweight object. Reuse if possible, and call Close when you're done (unless your program is terminating).
We should document the Close method better.
@jba that'd be my gut feeling as well. However it's not immediately obvious to me. Moreover, what's not clear to me is: is Client doing connection pooling? If not, should I implement it myself, because I think my requests might be getting serialized if the client.conn is a single connection?
I found this to be a friction myself while developing an app on top of Datastore using Go, hence I鈥檓 reporting it. I think it would be helpful to document this explicitly. If the Client godoc would say "we do connection pooling for you, don't worry, just Close() when you're done", that'd be very ideal, but as you can understand, I still don鈥檛 know what the behavior is so my question still stands.
@jba do you have any answers to my question above?
The cloud.google.com/go/datastore client does not do connection-pooling by default Use the WithGRPCConnectionPool option to create a pool.
Should we document this behavior? I think it's worth being verbose about which clients do pooling, whether users should close clients and such semantics.
Agreed.
So the action item for this bug is: for each package in this repo, document:
I feel like all clients should do pooling. Why doesn't it?
Having "GRPC" in the option name feels bad to me. We should avoid exposing implementation details like what type of transport is used. Why not just "WithConnectionPoolSize(int)"?
Hello! Some of our clients use http, and some use grpc. Here are more details about these usages:
http
MaxIdleConnsPerHost and MaxIdleConns. For the clients that use http, these options can be configured in an http client which can be passed in with WithHTTPClient.IdleConnTimeout setting.grpc
GOMAXPROCS (as mentioned before), although the size can be changed with WithGRPCConnectionPool option. Some clients do not specific a resolver, which causes the passthrough resolver to be used (essentially pool size of 1). Users can force a pool to be used and set the size with the WithGRPCConnectionPool option.x transport connections to the address where x = poolSize, and then round robin requests between the conns, as opposed to the aforementioned "first available" basis.KeepAlive setting.Answering some questions in this thread:
WithConnectionPool(size), since that guarantee isn't something we can make for http conns.WithGRPCConnectionPool, you will get pooling.@jadekler Thanks for the thorough work. It would be great to capture the gist of these deductions and filter those that are relevant to the users and include in package or Client godocs. For example, in storage.Client, I'd love to see something like "This client internally provides connection pooling.".
SGTM, I'll make a doc pass on this.
@ahmetb @broady Further investigation reveals that it's not easy to change HTTP transport settings, since supplying your own HTTP client causes yours to be used immediately without getting all the nice auth goodies that users normally get.
Not sure if any user cares much about this (in my experience most people are very OK with the default transport settings vis-脿-vis caching conns), but thought I'd mention.
I'm completely fine with not being able to update the settings, what I'm more interested in is surfacing the underlying transport/pooling information on the Client godocs.
Most helpful comment
I feel like all clients should do pooling. Why doesn't it?
Having "GRPC" in the option name feels bad to me. We should avoid exposing implementation details like what type of transport is used. Why not just "WithConnectionPoolSize(int)"?