Skip to content

Commit 68f1307

Browse files
committed
dashboard: share Spanner clients
Instead of creating a new Spanner client/connection per each DB operation, cache the clients per each appID. In normal operation, there will be just one appID and one client. For tests, we create a different appID per each NewSpannerCtx anyway.
1 parent 43e1df1 commit 68f1307

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

dashboard/app/aidb/crud.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"reflect"
1010
"strings"
11+
"sync"
1112
"time"
1213

1314
"cloud.google.com/go/spanner"
@@ -236,17 +237,37 @@ func selectOne[T any](ctx context.Context, stmt spanner.Statement) (*T, error) {
236237
return all[0], nil
237238
}
238239

240+
var clients sync.Map // map[string]*spanner.Client
241+
239242
func dbClient(ctx context.Context) (*spanner.Client, error) {
243+
appID := appengine.AppID(ctx)
244+
if v, ok := clients.Load(appID); ok {
245+
return v.(*spanner.Client), nil
246+
}
240247
path := fmt.Sprintf("projects/%v/instances/%v/databases/%v",
241-
appengine.AppID(ctx), Instance, Database)
242-
// TODO(dvyukov): create a persistent client with a pool of connections for prod,
243-
// but keep transient/per-test clients for tests.
244-
return spanner.NewClientWithConfig(ctx, path, spanner.ClientConfig{
248+
appID, Instance, Database)
249+
client, err := spanner.NewClientWithConfig(context.Background(), path, spanner.ClientConfig{
245250
SessionPoolConfig: spanner.SessionPoolConfig{
246251
MinOpened: 1,
247-
MaxOpened: 1,
252+
MaxOpened: 20,
248253
},
249254
})
255+
if err != nil {
256+
return nil, err
257+
}
258+
if actual, loaded := clients.LoadOrStore(appID, client); loaded {
259+
// The client was already created in parallel, close it.
260+
client.Close()
261+
return actual.(*spanner.Client), nil
262+
}
263+
return client, nil
264+
}
265+
266+
func CloseClient(ctx context.Context) {
267+
appID := appengine.AppID(ctx)
268+
if v, ok := clients.LoadAndDelete(appID); ok {
269+
v.(*spanner.Client).Close()
270+
}
250271
}
251272

252273
var TimeNow = func(ctx context.Context) time.Time {

dashboard/app/util_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ func (ctx *Ctx) Close() {
301301
}
302302
}
303303
}
304+
aidb.CloseClient(ctx.ctx)
304305
unregisterContext(ctx)
305306
validateGlobalConfig()
306307
}

0 commit comments

Comments
 (0)