I've had a bunch of issues migrating from App Engine on Go 1.9 to 1.11.
I noticed the memory usage grew insanely when I followed the guide how to migrate. Before it was at a constant ~50-60 MB, but now it grew to 1.5 GB quickly and instances started failing.
But then I noticed that all examples showing how to use the GCP Datastore just replaced the previous
datastore.Get()
with
dsClient := datastore.NewClient(...) dsClient.get()
Then, when I looked closer at this client, it created a connection but never seem to close it, so when I added a defer dsClient.Close()
after I created a new client (basically in every call handler), the memory started going up from around ~60-80 MB to ~500 MB and then dropped; it kept going like this, but it was stable so I figured it did a GC every now and then. However, after a couple days it failed again and requests took forever and new instances were created until the cap was reached (previously it failed quicker).
So I wonder if I should just create one Datastore Client in main instead? Is it a good practice? And, if so, why do all examples show it being created in the call handle, and why is there never call to close the connection?
Thanks!
I almost did the same but the godoc says to create a single client and reuse it for all datastore operations. There is no need to close the connection.
// Create a datastore client. In a typical application, you would create
// a single client which is reused for every datastore operation.
dsClient, err := datastore.NewClient(ctx, "my-project")
if err != nil {
// Handle error.
}