diff --git a/internal/cloudsql/instance.go b/internal/cloudsql/instance.go index 57e05543..411a29c9 100644 --- a/internal/cloudsql/instance.go +++ b/internal/cloudsql/instance.go @@ -158,7 +158,11 @@ func (i *Instance) OpenConns() *uint64 { // Close closes the instance; it stops the refresh cycle and prevents it from // making additional calls to the Cloud SQL Admin API. func (i *Instance) Close() error { + i.mu.Lock() + defer i.mu.Unlock() i.cancel() + i.cur.cancel() + i.next.cancel() return nil } @@ -254,6 +258,8 @@ func (i *Instance) refreshOperation(ctx context.Context) (*refreshOperation, err err = cur.err case <-ctx.Done(): err = ctx.Err() + case <-i.ctx.Done(): + err = i.ctx.Err() } if err != nil { return nil, err @@ -285,6 +291,13 @@ func (i *Instance) scheduleRefresh(d time.Duration) *refreshOperation { r := &refreshOperation{} r.ready = make(chan struct{}) r.timer = time.AfterFunc(d, func() { + // instance has been closed, don't schedule anything + if err := i.ctx.Err(); err != nil { + r.err = err + close(r.ready) + return + } + ctx, cancel := context.WithTimeout(i.ctx, i.refreshTimeout) defer cancel() @@ -304,13 +317,6 @@ func (i *Instance) scheduleRefresh(d time.Duration) *refreshOperation { close(r.ready) - select { - case <-i.ctx.Done(): - // instance has been closed, don't schedule anything - return - default: - } - // Once the refresh is complete, update "current" with working // refreshOperation and schedule a new refresh i.mu.Lock() diff --git a/internal/cloudsql/instance_test.go b/internal/cloudsql/instance_test.go index 3665759b..a30da211 100644 --- a/internal/cloudsql/instance_test.go +++ b/internal/cloudsql/instance_test.go @@ -19,7 +19,6 @@ import ( "crypto/rand" "crypto/rsa" "errors" - "strings" "testing" "time" @@ -223,7 +222,7 @@ func TestClose(t *testing.T) { i.Close() _, _, err = i.ConnectInfo(ctx, PublicIP) - if !strings.Contains(err.Error(), "context was canceled or expired") { + if !errors.Is(err, context.Canceled) { t.Fatalf("failed to retrieve connect info: %v", err) } }